Запросы Python-печать всего http-запроса (raw)?



при использовании requests модуль, есть ли способ распечатать необработанный HTTP-запрос?



Мне нужны не только заголовки, мне нужна строка запроса, заголовки и распечатка содержимого. Можно ли увидеть, что в конечном итоге строится из HTTP-запроса?

710   5  

5 ответов:

С v1.2.3 запросы добавили объект PreparedRequest. Согласно документации "он содержит точные байты, которые будут отправлены на сервер".

можно использовать это, чтобы довольно напечатать запрос, например:

import requests

req = requests.Request('POST','http://stackoverflow.com',headers={'X-Custom':'Test'},data='a=1&b=2')
prepared = req.prepare()

def pretty_print_POST(req):
    """
    At this point it is completely built and ready
    to be fired; it is "prepared".

    However pay attention at the formatting used in 
    this function because it is programmed to be pretty 
    printed and may differ from the actual request.
    """
    print('{}\n{}\n{}\n\n{}'.format(
        '-----------START-----------',
        req.method + ' ' + req.url,
        '\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
        req.body,
    ))

pretty_print_POST(prepared)

что производит:

-----------START-----------
POST http://stackoverflow.com/
Content-Length: 7
X-Custom: Test

a=1&b=2

тогда вы можете отправить фактический запрос с этим:

s = requests.Session()
s.send(prepared)

эти ссылки относятся к последней доступной документации, поэтому они могут измениться в содержании: передовая - Подготовленные запросы и API-классы нижнего уровня

Примечание: этот ответ устарел. Новые версии requests поддержка получения содержимого запроса напрямую, как ответ Антониохеррайза документы.

это не возможно, чтобы получить правда необработанное содержимое запроса из requests, так как он имеет дело только с объектами более высокого уровня, таких как заголовки и тип метода. requests использует urllib3 отправлять запросы, но urllib3и не имеет дело с необработанными данными-он использует httplib. Вот репрезентативная трассировка стека запроса:

-> r= requests.get("http://google.com")
  /usr/local/lib/python2.7/dist-packages/requests/api.py(55)get()
-> return request('get', url, **kwargs)
  /usr/local/lib/python2.7/dist-packages/requests/api.py(44)request()
-> return session.request(method=method, url=url, **kwargs)
  /usr/local/lib/python2.7/dist-packages/requests/sessions.py(382)request()
-> resp = self.send(prep, **send_kwargs)
  /usr/local/lib/python2.7/dist-packages/requests/sessions.py(485)send()
-> r = adapter.send(request, **kwargs)
  /usr/local/lib/python2.7/dist-packages/requests/adapters.py(324)send()
-> timeout=timeout
  /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py(478)urlopen()
-> body=body, headers=headers)
  /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py(285)_make_request()
-> conn.request(method, url, **httplib_request_kw)
  /usr/lib/python2.7/httplib.py(958)request()
-> self._send_request(method, url, body, headers)

внутри httplib машины, мы видим HTTPConnection._send_request косвенно использует HTTPConnection._send_output, который, наконец, создает необработанный запрос и тело (если оно существует), и использует HTTPConnection.send отправить их отдельно. send наконец, достигает гнезда.

так как нет крючков для делать то, что вы хотите, в крайнем случае вы можете обезьяна патч httplib получить содержание. Это хрупкое решение, и вам, возможно, придется адаптировать его, если httplib изменяется. Если вы собираетесь распространять программное обеспечение с помощью этого решения, вы можете рассмотреть возможность упаковки httplib вместо использования системы, что легко, так как это чистый модуль python.

увы, без лишних слов, решение:

import requests
import httplib

def patch_send():
    old_send= httplib.HTTPConnection.send
    def new_send( self, data ):
        print data
        return old_send(self, data) #return is not necessary, but never hurts, in case the library is changed
    httplib.HTTPConnection.send= new_send

patch_send()
requests.get("http://www.python.org")

, который дает на выходе:

GET / HTTP/1.1
Host: www.python.org
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/2.1.0 CPython/2.7.3 Linux/3.2.0-23-generic-pae

еще лучше использовать библиотеку requests_toolbelt, которая может выводить как запросы, так и ответы в виде строк для печати на консоль. Он обрабатывает все сложные случаи с файлами и кодировками, которые выше решение не справляется хорошо.

это так же просто, как это:

import requests
from requests_toolbelt.utils import dump

resp = requests.get('https://httpbin.org/redirect/5')
data = dump.dump_all(resp)
print(data.decode('utf-8'))

Источник:https://toolbelt.readthedocs.org/en/latest/dumputils.html

Вы можете просто установить его, введя:

pip install requests_toolbelt
import requests
response = requests.post('http://httpbin.org/post', data={'key1':'value1'})
print(response.request.body)
print(response.request.headers)

Я использую запросы версия 2.18.4 и Python 3

вот код, который делает то же самое, но с заголовками ответ:

import socket
def patch_requests():
    old_readline = socket._fileobject.readline
    if not hasattr(old_readline, 'patched'):
        def new_readline(self, size=-1):
            res = old_readline(self, size)
            print res,
            return res
        new_readline.patched = True
        socket._fileobject.readline = new_readline
patch_requests()

Я потратил много времени на поиски этого, поэтому я оставляю его здесь, если кому-то нужно.

Comments

    Ничего не найдено.