Come posso vedere l'intera richiesta HTTP che viene inviata dalla mia applicazione Python?


263

Nel mio caso, sto usando la requestslibreria per chiamare l'API di PayPal su HTTPS. Sfortunatamente, ricevo un errore da PayPal e il supporto PayPal non è in grado di capire quale sia l'errore o cosa lo stia causando. Vogliono che "Fornisca l'intera richiesta, intestazioni incluse".

Come lo posso fare?

Risposte:


499

Un metodo semplice: abilita la registrazione nelle ultime versioni di Requests (1.xe successive).

Requests utilizza la configurazione del modulo http.cliente loggingper controllare la verbosità della registrazione, come descritto qui .

Dimostrazione

Codice estratto dalla documentazione collegata:

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')

Esempio di output

$ 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
Grazie, @ EmmettJ.Butler =) Anche se non sono sicuro che queste informazioni fossero disponibili al momento della richiesta originale.
Inattivista,

9
Nota che httplib non è disponibile su Python 3. Per rendere il codice portatile, sostituiscilo import httplibcon import requests.packages.urllib3.connectionpool as httplibo usa six e from six.moves import http_client as httplib.
Jason R. Coombs,

In requests2.18.1 e Python 3, il logger logging.getLogger("requests.packages.urllib3")non esiste o non ha alcun effetto.
Flimm,

1
per Python3 vedi qui - docs.python-requests.org/en/latest/api/?highlight=debug from http.client import HTTPConnection
shershen

Sfortunatamente le righe "send:" "reply:" e "header:" non sono effettivamente registrate, ma sono stampate su stdout. Ma voglio avere queste informazioni nei file di registro!
Lesnik,

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

rè una risposta. Ha un attributo di richiesta che ha le informazioni necessarie.

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 dà le intestazioni:

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

Quindi r.request.dataha il corpo come una mappatura. Puoi convertirlo con urllib.urlencodese preferiscono:

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

a seconda del tipo di risposta l' .dataattributo -attributo potrebbe mancare e al .bodysuo posto dovrebbe esserci un attributo.


14
Quale di questi mi dà "l'intera richiesta, intestazioni incluse"?
Chris B.

1
aggiunto un po 'di più. Di cos'altro hai bisogno oltre alle intestazioni e al corpo?
Skylar Saveland,

8
Non sono del tutto sicuro di cosa stiano cercando. Speravo di catturare tutto ciò che andava oltre il filo per loro, in quel formato esatto, byte per byte.
Chris B.

18
Questo è il modo preferito di farlo nel mio caso. Solo una nota: response.requestsembra essere una PreparedRequestnel mio caso; non ha .datama .bodyinvece.
Antti Haapala,

2
per l'URL completo (con i parametri di querystring) puoi anche usare response.url (che è un po 'diverso in quanto non lo èresponse.request...
Chuck van der Linden,

7

È possibile utilizzare HTTP Toolkit per fare esattamente questo.

È particolarmente utile se devi farlo rapidamente, senza modifiche al codice: puoi aprire un terminale da HTTP Toolkit, eseguire qualsiasi codice Python da lì normalmente e sarai in grado di vedere l'intero contenuto di ogni HTTP / HTTPS richiedi immediatamente.

Esiste una versione gratuita che può fare tutto il necessario ed è open source al 100%.

Sono il creatore di HTTP Toolkit; In realtà l'ho costruito io stesso per risolvere lo stesso identico problema per me qualche tempo fa! Anch'io stavo cercando di eseguire il debug di un'integrazione di pagamento, ma il loro SDK non funzionava, non sapevo dire perché e dovevo sapere cosa stava realmente succedendo per risolverlo correttamente. È molto frustrante, ma essere in grado di vedere il traffico non elaborato aiuta davvero.


5

Se stai usando Python 2.x, prova a installare un dispositivo di apertura urllib2 . Questo dovrebbe stampare le tue intestazioni, anche se potresti doverlo combinare con altri apri che stai usando per colpire l'HTTPS.

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

2

L' verboseopzione di configurazione potrebbe consentire di vedere ciò che si desidera. C'è un esempio nella documentazione .

NOTA: leggere i commenti seguenti: le opzioni di configurazione dettagliate non sembrano più disponibili.


3
C'è? Non riesco davvero a trovarlo.
BastiBen,

3
@gatto cattivo. C'era una sezione "Registrazione dettagliata" al momento . Sembra che sia stato rimosso a dicembre .
Bruno

2
Ah, questo spiegherebbe quello. :) Tuttavia, ora questa domanda è di nuovo valida, perché non sono riuscito a trovare un modo per stampare l'intero traffico tra server e client per il debug.
BastiBen,

1
Esiste un "nuovo modo" raccomandato per ottenere lo stesso effetto della registrazione dettagliata?
cbare

1
La mia risposta dimostra il metodo corretto per le richieste 1.xe successive.
Inattivista,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.