Як я бачу весь HTTP-запит, який надсилається моєю програмою Python?


263

У моєму випадку я використовую requestsбібліотеку для виклику API PayPal через HTTPS. На жаль, я отримую помилку від PayPal, і підтримка PayPal не може з'ясувати, що це за помилка чи що її викликає. Вони хочуть, щоб я "Будь ласка, надайте весь запит, включені заголовки".

Як я можу це зробити?

Відповіді:


498

Простий метод: увімкнути вхід в останні версії запитів (1.x і вище.)

Запити використовують конфігурацію модуля http.clientта loggingдля керування вербологією журналу, як описано тут .

Демонстрація

Код вилучений із зв'язаної документації:

import requests
import logging

# These two lines enable debugging at httplib level (requests->urllib3->http.client)
# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# The only thing missing will be the response.body which is not logged.
try:
    import http.client as http_client
except ImportError:
    # Python 2
    import httplib as http_client
http_client.HTTPConnection.debuglevel = 1

# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

requests.get('https://httpbin.org/headers')

Приклад Вихід

$ python requests-logging.py 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): httpbin.org
send: 'GET /headers HTTP/1.1\r\nHost: httpbin.org\r\nAccept-Encoding: gzip, deflate, compress\r\nAccept: */*\r\nUser-Agent: python-requests/1.2.0 CPython/2.7.3 Linux/3.2.0-48-generic\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Type: application/json
header: Date: Sat, 29 Jun 2013 11:19:34 GMT
header: Server: gunicorn/0.17.4
header: Content-Length: 226
header: Connection: keep-alive
DEBUG:requests.packages.urllib3.connectionpool:"GET /headers HTTP/1.1" 200 226

1
Дякую, @ EmmettJ.Butler =) Хоча я не впевнений, що ця інформація була доступна під час первинного запиту.
Інактивіст

9
Зверніть увагу , що HTTPLIB не доступно на Python 3. Для того, щоб зробити код портативним, замінити import httplibз import requests.packages.urllib3.connectionpool as httplibабо використовувати шість і from six.moves import http_client as httplib.
Джейсон Р. Кумбс

У requests2.18.1 та Python 3 реєстратор logging.getLogger("requests.packages.urllib3")не існує або не має ефекту.
Flimm

1
для Python3 дивіться тут - docs.python-requests.org/en/latest/api/?highlight=debug from http.client import HTTPConnection
shershen

На жаль, рядки "send:" "reply:" та "header:" насправді не реєструються, а просто надрукуються до stdout. Але я хочу, щоб ця інформація була у файлах журналів!
lesnik

145
r = requests.get('https://api.github.com', auth=('user', 'pass'))

rє відповіддю. Він має атрибут запиту, який містить необхідну інформацію.

r.request.allow_redirects  r.request.headers          r.request.register_hook
r.request.auth             r.request.hooks            r.request.response
r.request.cert             r.request.method           r.request.send
r.request.config           r.request.params           r.request.sent
r.request.cookies          r.request.path_url         r.request.session
r.request.data             r.request.prefetch         r.request.timeout
r.request.deregister_hook  r.request.proxies          r.request.url
r.request.files            r.request.redirect         r.request.verify

r.request.headers дає заголовки:

{'Accept': '*/*',
 'Accept-Encoding': 'identity, deflate, compress, gzip',
 'Authorization': u'Basic dXNlcjpwYXNz',
 'User-Agent': 'python-requests/0.12.1'}

Потім r.request.dataмає тіло як відображення. Ви можете перетворити це за допомогою, urllib.urlencodeякщо вони бажають:

import urllib
b = r.request.data
encoded_body = urllib.urlencode(b)

залежно від типу відповіді .data-attribute може бути відсутнім, а .body-attribute бути там.


14
Що з них дає мені "весь запит, включені заголовки"?
Кріс Б.

1
додали ще трохи. Що ще потрібно крім заголовків та корпусу?
Скайлар Савеленд

8
Я не зовсім впевнений, що вони шукають. Я сподівався зафіксувати все, що перейшло за ними, у такому точному форматі, байт-байт.
Кріс Б.

18
Це найкращий спосіб зробити це в моєму випадку. Лише одна примітка: response.requestздається, що PreparedRequestв моєму випадку є; у нього немає, .dataале .bodyнатомість.
Антті Хаапала

2
для повної URL-адреси (з параметрами запиту) ви також можете скористатися response.url (що дещо відрізняється тим, що це не такresponse.request...
Чак ван дер Лінден

6

Ви можете використовувати HTTP Toolkit, щоб зробити це саме так.

Це особливо корисно, якщо вам потрібно зробити це швидко, без змін коду: ви можете відкрити термінал з HTTP Toolkit, запустити звідти будь-який код Python як звичайний, і ви зможете побачити повний вміст кожного HTTP / HTTPS запит негайно.

Є безкоштовна версія, яка може робити все необхідне, і це 100% відкритий код.

Я творець інструментарію HTTP; Я насправді побудував це сам, щоб вирішити ту саму проблему для мене на той час! Я теж намагався налагодити інтеграцію платежів, але їх SDK не працював, я не міг сказати чому, і мені потрібно було знати, що насправді відбувається, щоб правильно його виправити. Це дуже засмучує, але можливість бачити необроблений трафік справді допомагає.


5

Якщо ви використовуєте Python 2.x, спробуйте встановити відкривач urllib2 . Це повинно надрукувати заголовки, хоча, можливо, вам доведеться поєднувати це з іншими відкривачами, якими ви користуєтесь, щоб потрапити на HTTPS.

import urllib2
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)))
urllib2.urlopen(url)

2

Опція verboseконфігурації може дозволяти вам бачити, що ви хочете. У документації є приклад .

ПРИМІТКА. Прочитайте коментарі нижче: Параметри багатослівної конфігурації більше не доступні.


3
Є? Неможливо насправді її знайти.
BastiBen


2
Ах, це пояснило б це. :) І все-таки тепер це питання знову є справедливим, тому що я не міг знайти спосіб надрукувати весь трафік між сервером та клієнтом для налагодження.
BastiBen

1
Чи рекомендований "новий спосіб" досягти такого ж ефекту, як і багатослівний журнал?
cbare

1
Моя відповідь демонструє правильний метод для запитів 1.x і вище.
Інактивіст
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.