注意:此答案已过时。较新版本的requests 支持直接获取请求内容,如AntonioHerraizS's answer 文档。
不可能从requests 中获取请求的true 原始内容,因为它只处理更高级别的对象,例如headers 和方法类型。 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