как отлаживать библиотеку запросов?

Я пытаюсь преобразовать свой скрипт python с выдачи команды curl через os.system() на использование запросов. Я думал, что буду использовать pycurl, но этот вопрос убедил меня в обратном. Проблема в том, что с сервера возвращается ошибка, которую я вижу при использовании r.text (из этого ответа), но мне нужна дополнительная информация. Есть ли лучший способ отладить то, что происходит?

для чего это стоит, я думаю, что проблема связана с преобразованием моего флага --data из curl/pycurl в запросы. Я создал словарь параметров, которые я передал в --data раньше. Я предполагаю, что один из них недействителен, но как я могу получить больше информации, чтобы знать наверняка?

пример:

headers2 = {"Accept":"*/*", \
"Content-Type":"application/x-www-form-urlencoded", \
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36", \
"Origin":"https://somedomain.com", \
"X-Requested-With":"XMLHttpRequest", \
"Connection":"keep-alive", \
"Accept-Language":"en-US,en;q=0.8", \
"Referer":"https://somedomain.com/release_cr_new.html?releaseid=%s&v=2&m=a&prev_release_id=%s" % (current_release_id, previous_release_id), \
"Host":"somedomain.com", \
"Accept-Encoding":"gzip,deflate,sdch", \
"Cookie":'cookie_val'}

for bug_id in ids:
  print bug_id
  data = {'dump_json':'1','releaseid':current_release_id, 'v':'2','m':'a','prev_release_id': previous_release_id,'bug_ids': bug_id, 'set_cols':'sqa_status&sqa_updates%5B0%5D%5Bbugid%5D=' + bug_id + '&sqa_updates%5B0%5D%5Bsqa_status%5D=6'}
  print 'current_release_id' , data['releaseid']
  print 'previous_release_id', data['prev_release_id']
  r = requests.post(post_url, data=json.dumps(data), headers=headers2)
  print r.text

Вывод, который я получаю, представляет собой довольно общее html-сообщение, которое я видел раньше, когда неправильно запрашивал сервер. Так что я знаю, что я достиг нужного сервера по крайней мере.

Я действительно не ожидаю никакого результата. Это должно просто отправить на сервер и обновить поле в БД.


person Ramy    schedule 27.09.2013    source источник
comment
Можете ли вы опубликовать пример (включая ввод, ожидаемый вывод и фактический вывод)? Вы можете указать на http://httpbin.org/ (вы можете разветвить на github, если вы не хотите отправлять туда свои данные) . Это может помочь вам в отладке различий.   -  person Wayne Werner    schedule 27.09.2013
comment
Я попытался обновить его с помощью примера. Сначала я не решался сделать это, потому что я, как известно, плохо оставляю что-то, что я должен замаскировать.   -  person Ramy    schedule 27.09.2013
comment
я немного поиграл с кодировкой - полностью удалил ее без каких-либо изменений в результате.   -  person Ramy    schedule 27.09.2013


Ответы (2)


Анатомия http-ответа

Пример (загрузка этой страницы)

HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Expires: Fri, 27 Sep 2013 19:22:41 GMT
Last-Modified: Fri, 27 Sep 2013 19:21:41 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Fri, 27 Sep 2013 19:21:41 GMT
Content-Length: 12706

<!DOCTYPE html>
<html>
... truncated rest of body ...
  1. Первая строка — это строка состояния, состоящая из кода состояния и текста состояния.
  2. Заголовки — это пары "ключ-значение". Заголовки заканчиваются пустой новой строкой. Пустая строка означает, что заголовков больше нет, и следует начало полезной нагрузки/тела.
  3. body использует остальную часть сообщения.

Ниже объясняется, как извлечь 3 части:

Строка состояния

Используйте следующее, чтобы получить строку состояния, отправленную с сервера

>>> bad_r = requests.get('http://httpbin.org/status/404')
>>> bad_r.status_code
404

>>> bad_r.raise_for_status()
Traceback (most recent call last):
  File "requests/models.py", line 832, in raise_for_status
    raise http_error
requests.exceptions.HTTPError: 404 Client Error

(источник)

Заголовки:

r = requests.get('http://en.wikipedia.org/wiki/Monty_Python')
# response headers: 
r.headers
# request headers:
r.request.headers

Тело

Используйте r.text.

Кодирование пост-запроса

«Тип контента», который вы отправляете на сервер в запросе, должен соответствовать типу контента, который вы фактически отправляете. В вашем случае вы отправляете json, но сообщаете серверу, что отправляете данные формы (это значение по умолчанию, если вы не укажете).

Из заголовков, которые вы показываете выше:

"Content-Type":"application/x-www-form-urlencoded",

Но ваш вызов request.post устанавливает data=json.dumps(data), который является JSON. В заголовках должно быть указано:

"Content-type": "application/json",

person Jonathan    schedule 27.09.2013
comment
отлично! Итак, я просто скопировал json.dumps фрагмент вслепую. Форма-urlencoded является правильным типом кодирования. Я изменил это на data=data, и теперь ответ кажется более точным, но он не совсем соответствует моим ожиданиям. Я приму этот ответ, покопаюсь еще. - person Ramy; 27.09.2013

Значение, возвращаемое из объекта request, содержит информацию о запросе в разделе .request.

Пример:

r = requests.request("POST", url, ...)

print("Request headers:", r.request.headers)
print("Request body:", r.request.body)

print("Response status code:", r.status_code)
print("Response text:", r.text.encode('utf8'))
person aled    schedule 07.07.2020