397 Stimmen

Wie kann ich die gesamte HTTP-Anfrage sehen, die von meiner Python-Anwendung gesendet wird?

In meinem Fall verwende ich die requests Bibliothek, um die API von PayPal über HTTPS aufzurufen. Leider bekomme ich eine Fehlermeldung von PayPal, und der PayPal-Support kann nicht herausfinden, was der Fehler ist oder was ihn verursacht. Sie wollen, dass ich "bitte die gesamte Anfrage, einschließlich der Kopfzeilen, bereitstelle".

Wie kann ich das tun?

715voto

Inactivist Punkte 9149

Eine einfache Methode: Aktivieren Sie die Protokollierung in neueren Versionen von Requests (1.x und höher).

Requests verwendet die http.client y logging Modulkonfiguration zur Steuerung der Ausführlichkeit der Protokollierung, wie beschrieben aquí .

Demonstration

Der Code stammt aus der verlinkten Dokumentation:

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

Beispiel Ausgabe

$ 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

214voto

Skylar Saveland Punkte 10479
r = requests.get('https://api.github.com', auth=('user', 'pass'))

r ist eine Antwort. Sie hat ein Attribut request, das die benötigten Informationen enthält.

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 gibt die Kopfzeilen an:

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

Dann r.request.data hat den Körper als Mapping. Sie können dies mit urllib.urlencode wenn sie dies wünschen:

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

abhängig von der Art der Antwort die .data -Attribut kann fehlen und ein .body -Attribut vorhanden sein.

23voto

Tim Perry Punkte 9895

Sie können verwenden HTTP-Werkzeugsatz um genau dies zu tun.

Es ist besonders nützlich, wenn Sie dies schnell und ohne Code-Änderungen tun müssen: Sie können ein Terminal aus dem HTTP-Toolkit heraus öffnen, jeden Python-Code von dort aus wie gewohnt ausführen, und Sie werden in der Lage sein, den vollständigen Inhalt jeder HTTP/HTTPS-Anfrage sofort zu sehen.

Es gibt eine kostenlose Version, die alles kann, was Sie brauchen, und sie ist zu 100 % Open Source.

Ich bin der Schöpfer des HTTP-Toolkits; ich habe es tatsächlich selbst entwickelt, um genau das gleiche Problem zu lösen, das ich vor einiger Zeit hatte! Auch ich habe versucht, eine Zahlungsintegration zu debuggen, aber ihr SDK hat nicht funktioniert, ich konnte nicht sagen, warum, und ich musste wissen, was tatsächlich los war, um es richtig zu beheben. Es ist sehr frustrierend, aber es hilft wirklich, wenn man den Rohdatenverkehr sehen kann.

12voto

Gian Segato Punkte 2289

Eine viel einfachere Methode zur Fehlersuche bei lokalen HTTP-Anfragen ist die Verwendung von netcat. Wenn Sie

nc -l 1234

werden Sie auf dem Port 1234 für HTTP-Verbindungen. Sie können darauf zugreifen über http://localhost:1234/foo/foo/... .

Auf dem Terminal sehen Sie die Rohdaten, die Sie an den Endpunkt gesendet haben. Zum Beispiel:

POST /foo/foo HTTP/1.1
Accept: application/json
Connection: keep-alive
Host: example.com
Accept-Language: en-en
Authorization: Bearer ay...
Content-Length: 15
Content-Type: application/json

{"test": false}

9voto

squalou Punkte 169

Kein Logging-System funktioniert vollständig (ab Version 2.26 sowieso, sehr alte Versionen hatten vielleicht ein anderes Verhalten)

Eine gute Lösung ist es, "Haken" zu verwenden und Details zu drucken, wenn sie passieren.

Dies wird hier recht gut erklärt: https://findwork.dev/blog/advanced-usage-python-requests-timeouts-retries-hooks/

unter "alles drucken",

aber für den Fall, dass der Link nicht funktioniert, hier die wichtigsten Teile

import requests
from requests_toolbelt.utils import dump

def logging_hook(response, *args, **kwargs):
    data = dump.dump_all(response)
    print(data.decode('utf-8'))

http = requests.Session()
http.hooks["response"] = [logging_hook]

http.get("https://api.openaq.org/v1/cities", params={"country": "BA"})

Das Ergebnis wird diesmal eine vollständige Aufzeichnung der gesendeten Anfrage und der empfangenen Antwort sein.

Ich habe es erfolgreich mit POST und vielen Headern ausprobiert: es funktioniert. Vergessen Sie nicht, pip zu installieren requests_toolbelt.

# Output
< GET /v1/cities?country=BA HTTP/1.1
< Host: api.openaq.org

> HTTP/1.1 200 OK
> Content-Type: application/json; charset=utf-8
> Transfer-Encoding: chunked
> Connection: keep-alive
>
{
   "meta":{
      "name":"openaq-api",
      "license":"CC BY 4.0",
      "website":"https://docs.openaq.org/",
      "page":1,
      "limit":100,
      "found":1
   },
   "results":[
      {
         "country":"BA",
         "name":"Goražde",
         "city":"Goražde",
         "count":70797,
         "locations":1
      }
   ]
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X