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?

7voto

Aaron Beaudoin Punkte 243

Eine frühere Antwort scheint heruntergestuft worden zu sein, weil sie mit "nichts funktioniert vollständig" begann und dann diese perfekte Lösung bietet:

  1. Installieren Sie die requests_toolbelt Sammlung von Dienstprogrammen mit pip install requests-toolbelt .
  2. Verwenden Sie es so:

    import requests
    from requests_toolbelt.utils import dump
    
    response = requests.get("https://v2.jokeapi.dev/joke/Any?safe-mode")
    print(dump.dump_all(response).decode("utf-8"))

6voto

Kafonek Punkte 362

Wenn Sie Python 2.x verwenden, installieren Sie eine urllib2 Öffner. Das sollte Ihre Header ausdrucken, obwohl Sie das möglicherweise mit anderen Openern kombinieren müssen, die Sie verwenden, um HTTPS zu erreichen.

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

2voto

Bruno Punkte 114719

En verbose Konfigurationsoption können Sie vielleicht sehen, was Sie wollen. Es gibt ein Beispiel in der Dokumentation .

HINWEIS: Lesen Sie die Kommentare unten: Die ausführlichen Konfigurationsoptionen scheinen nicht mehr verfügbar zu sein.

2voto

reddot Punkte 615

Wie andere bereits erwähnt haben, gibt es eine schöne requests-toolbelt Modul mit praktischen Funktionen zum Auslesen von Anfrage- und Antwortinhalten unter Verwendung von Request-Hooks. Leider gibt es (bis jetzt) nur einen Hook, der bei erfolgreichem Abschluss einer Anfrage aufgerufen wird. Das ist nicht immer der Fall. D.h. eine Anfrage könnte enden mit ConnectionError o Timeout Ausnahmen.

En requests-toolbelt Modul selbst bietet auch öffentliche Funktionen, um nur abgeschlossene Anfragen auszulagern. Mit Hilfe von nicht-öffentlichen APIs und Session Sub-Classing ist es jedoch möglich, die Protokollierung von Anfragen vor dem Senden und die Protokollierung von Antworten nach dem Empfang zu implementieren.

HINWEIS: Der Code stützt sich auf Implementierungsdetails/nicht-öffentliche APIs von requests-toolbelt Modul und damit in Zukunft unerwartet zu brechen:

import requests

from requests_toolbelt.utils import dump

class MySession(requests.Session):
    def send(self, req, *args, **kwargs):
        prefixes = dump.PrefixSettings(b'< ', b'> ')

        data = bytearray()

        try:
            dump._dump_request_data(req, prefixes, data)
            resp = super().send(req, *args, **kwargs)
            dump._dump_response_data(resp, prefixes, data)
        finally:
            print(data.decode('utf-8'))

        return resp

und hier ist ein Beispiel für die Verwendung:

>>> MySession().get('https://httpbin.org/headers')
< GET /headers HTTP/1.1
< Host: httpbin.org
< User-Agent: python-requests/2.25.1
< Accept-Encoding: gzip, deflate
< Accept: */*
< Connection: keep-alive
< 

> HTTP/1.1 200 OK
> Date: Fri, 19 Aug 2022 10:43:51 GMT
> Content-Type: application/json
> Content-Length: 225
> Connection: keep-alive
> Server: gunicorn/19.9.0
> Access-Control-Allow-Origin: *
> Access-Control-Allow-Credentials: true
> 
{
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.25.1"
  }
}

>>> MySession().get('https://non.existent')
< GET / HTTP/1.1
< Host: non.existent
< User-Agent: python-requests/2.25.1
< Accept-Encoding: gzip, deflate
< Accept: */*
< Connection: keep-alive
< 

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 169, in _new_conn
    conn = connection.create_connection(
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 73, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
...

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