python requests爬虫如何print http raw请求?

python requests爬虫如何print http raw请求?

1、前言

  hello,各位码友,最近冷空气有点飕飕的,可得注意防寒,穿秋裤出来暖场,千万别取暖靠抖了。前面几篇咱们一直在selenium系列,咱们今天讨论一点其他的。

  进入正题。大家一般都使用python的requests库进行爬虫开发,在很多情况下,我们代码写好了,运行起来总是得不到想要的结果,要么是headers字典里面少加了点特定的键值,要么是忘了带cookie,还有就干脆发送的数据body或者query string有问题。

2、问题

  我们的问题在于如何记录原始的http请求,以便于我们知道实际发送给web服务器的http报文内容? 当然大家可以说在开发的时候,用fiddler或者charles抓下包,对比一下手动请求少了那些东西不就得了,但是要是在生产环境下出现问题了呢? 咱们不可能在生产环境下也时刻挂着抓包软件吧?今天我们就来介绍一种解决方案。

3、解决方案

  对于通过requests开发的爬虫代码来说,它最终都会调用更下层的发送报文的函数,我们只需要在它发送http报文之前,把原始的报文格式记录下来就能实现我们的目的。

  先直接看patch代码,对于python3和python2来说patch的位置不一样,下面的代码考虑了两个版本的情况。

import sys
if sys.version>'3':
    from urllib3.packages.six.moves import http_client as httplib
else:
    import httplib
def patch_send():
    old_send= httplib.HTTPConnection.send
    def new_send( self, data ):
        with open("requests.log","ab") as f:
            f.write(data)
        return old_send(self, data)
    httplib.HTTPConnection.send= new_send

  以上代码,定义了一个patch_send函数在做整个操作: - 1、在函数内部我们定义一个old_send函数相当于保持对原本的send函数对象的”引用“。 - 2、定义一个new_send函数,替换掉原生的http发送报文函数,在发送报文之前,我们先把报文写入本地的日志,然后再调用保存的old_send

  我们实际调用requests访问www.baidu.com:

def get_baidu():
    import requests
    response = requests.get("http://www.baidu.com", headers={
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36"})

def main():
    patch_send()
    get_baidu()


if __name__ == "__main__":
    main()

  测试结果,我们看看requests.log这个文件:

  我们发现日志里为记录两个一样的http报文请求,为什么会有两个?

  原因很简单,因为访问的http后,会跳转到https的baidu.com所以有两次请求。

防止失联,关注微信公众号:码道工程。

本文作者:小码哥

本文链接:http://www.tnt0.com/archives/11

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!

selenium爬虫使用代理的正确姿势... <<
0 条评论

请先登陆注册

已登录,注销 取消