• python之selenium wire获取请求头参数


    selenium-wire扩展了 Selenium 的 Python 绑定,让您可以访问浏览器发出的底层请求。 您编写代码的方式与使用 Selenium 的方式相同,但您可以获得额外的 API 来检查请求和响应并动态更改它们

    一:简介

    selenium是爬虫常用的手段之一,由于是使用浏览器驱动模拟手动操作,所以只要掌握一些元素的基本定位就很容易上手。
    但是经常会遇到的问题我觉得至少有两点:

    每次启动的浏览器都是一个全新的浏览器,不存在任何的缓存,换句话说如果网站需要登录则每次启动都需要登录,需要邮件验证码的网站就更难受了。
    现在大多数的网站都采用前后端分离+ajax技术,分析画面元素固然是可以的,但是如果能够获取浏览器后台的ajax数据,那简直是事半功倍。
    本次主要讨论的就是这两个问题,在之前我总结过一些相关的坑,包括浏览器的cookie操作、performance获取浏览器后台日志数据以及浏览器的代理认证框的处理问题,这也算是对之前的一次补充。

    二:Selenium利用本地浏览器进行测试

    是的,你没看错。由于驱动的是本地浏览器,本地浏览器有缓存,所以完美避免了浏览器的cookie问题。而且亲测,这种方式还可以直接解析浏览器当前网页,不需要启动新的浏览器,也就是说你可以预先登录到目标网站再运行程序。

    1、右键谷歌浏览器快捷方式->属性,在路径上追加参数 --remote-debugging-port=9222

    2、双击打开浏览器
    3、selenium远程模式连接浏览器并进行操作,这里测试控制浏览器打开百度。

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    chrome_options = Options()
    chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
    driver = webdriver.Chrome(options=chrome_options)
    driver.get("https://www.baidu.com")

    这样就已经可以了,跟正常的selenium操作没有任何区别。

    二、Selenium-wire获取后台数据

    (一)selenium-wire安装

    pip install selenium-wire

    实例1:

    import time
    from seleniumwire import webdriver
    
    # Create a new instance of the Chrome driver
    driver = webdriver.Chrome()
    # Go to the YouTube homepage.
    driver.get('http://tool.liumingye.cn/music/?page=audioPage&type=migu&name=%E6%8A%96%E9%9F%B3')
    time.sleep(5)
    # Access requests via the `requests` attribute
    for request in driver.requests:
        if request.response:
            if request.path == "/m/api/search":
                print(request.response.body.decode("utf-8"))
    driver.quit()

    封装后的driver会有requests这样一个对象,可以发跟浏览器开发者工具的Network进行类比,请求的返回值存储在response.body中。
    通过request.path过滤出我们想要的请求,然后获取response.body即可。

    运行结果如下:

    {"code":200,"data":{"list":[{"name":"把孤独当作晚餐(抖音版)","artist":"画词戏子","cover":"http:\/\/d.musicapp.migu.cn\/prod\/file-service\/file-down\/8121e8df41a5c12f48b69aea89b71dab\/0f0e94be13d0d18b4cd0f53996e0023b\/18bde3d3d5415eba88115dab279a8b4e","lrc":"http:\/\/59.110.45.28\/m\/api\/lrc\/migu\/id\/f8ceFzdyYgzcjzn5SuaHgUIARghxmB8jGoQIXczI3sOpkObywQMI-l8gtQ81JkoAm91NAZiVFqn2sz-LM7vsi7ycKuefN3JDZWHyMeVFO0toeLCawtmuafH-7iXPvu_lMWxYPkpA6-0-iyFzbqnwdaUWemgw6Ih2tmUPWXXHuA","url_m4a":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=LQ&netType=00&copyrightId=0&contentId=600913000005364995&resourceType=2&channel=0","url_128":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=PQ&netType=00&copyrightId=0&contentId=600913000005364995&resourceType=2&channel=0","url_320":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=HQ&netType=00&copyrightId=0&contentId=600913000005364995&resourceType=2&channel=0","url_flac":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=SQ&netType=00&copyrightId=0&contentId=600913000005364995&resourceType=E&channel=0","url":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=LQ&netType=00&copyrightId=0&contentId=600913000005364995&resourceType=2&channel=0"},{"name":"你走(抖音版)","artist":"松紧先生","cover":"http:\/\/d.musicapp.migu.cn\/prod\/file-service\/file-down\/b1899d500dda5db2da11df3efc89cba6\/d6ac70e448ff3cd5d545cf44d0d7a2c0\/c1690b3588064699c3688d676984331f","lrc":"http:\/\/59.110.45.28\/m\/api\/lrc\/migu\/id\/b30fUTX4wkz-oVd-f8y9OQ_kKBBi4zY2Aje7_xDOCt_kVgFl9nQjZo9U1oenDZiCAQJ6coUeJiWG7OGE9fc87A-z0llkBxgLJdxlW-_3LXaKxHkh29HDtMkYTExcEk20jfTXt_0BVLYaeBOf0dMAf4b0mFWQ5PQ6g1Bd7tPZ4w","url_m4a":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=LQ&netType=00&copyrightId=0&contentId=600919000000557974&resourceType=2&channel=0","url_128":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=PQ&netType=00&copyrightId=0&contentId=600919000000557974&resourceType=2&channel=0","url_320":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=HQ&netType=00&copyrightId=0&contentId=600919000000557974&resourceType=2&channel=0","url_flac":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=SQ&netType=00&copyrightId=0&contentId=600919000000557974&resourceType=E&channel=0","url":"http:\/\/218.205.239.34\/MIGUM2.0\/v1.0\/content\/sub\/listenSong.do?toneFlag=LQ&netType=00&copyrightId=0&contentId=600919000000557974&resourceType=2&channel=0"}}

    实例2:

    from seleniumwire import webdriver
    
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    
    # 通过requests属性访问请求
    for request in driver.requests:
        if request.response:
            print("Url:", request.url)
            print("Code:", request.response.status_code)
            print("Content-Type:", request.response.headers['Content-Type'])

    执行结果:

    实例3:设置拦截器

    可以在某些请求发出前,修改请求的参数或直接阻止请求

    import json
    from seleniumwire import webdriver
    
    # 设置拦截器
    def interceptor(request):
        # 拦截.png,.jpg,.gif结尾的请求
        if request.path.endswith(('.png', '.jpg', '.gif')):
            request.abort()
    
    driver = webdriver.Chrome()
    driver.request_interceptor = interceptor
    driver.get('https://www.baidu.com')
    
    # 通过requests属性访问请求
    for request in driver.requests:
        if request.response:
            print("Url:", request.url)
            print("Code:", request.response.status_code)
            print("Content-Type:", request.response.headers['Content-Type'])

    添加和修改请求参数

    # 设置拦截器
    def interceptor(request):
        # 添加请求参数
        params = request.params
        params['foo'] = 'bar'
        request.params = params
    
        # 修改POST请求正文中的JSON
        if request.method == 'POST' and request.headers['Content-Type'] == 'application/json':
            # 获取原请求内容
            body = request.body.decode('utf-8')
            data = json.loads(body)
            # 修改要改变的参数
            data['foo'] = 'bar'
            # 将修改好的参数设置回请求
            request.body = json.dumps(data).encode('utf-8')
            # 更新内容长度
            del request.headers['Content-Length']
            request.headers['Content-Length'] = str(len(request.body))
  • 相关阅读:
    [转]简单理解php的socket编程
    github 生成token的方法
    win7升级powershell【转】
    PHP的反射机制 【转】
    jquery幻灯片插件slick演示
    织梦生成的时候“你指定的文件名有问题,无法创建文件”解决方案【转】
    dedecms下的tplcache模板缓存[转]
    dede织梦data目录正确迁移及引起的问题解决方法【转】
    C# 判断是否是在设计模式下有效的方法
    C# 操作计算机用户权限
  • 原文地址:https://www.cnblogs.com/hushaojun/p/16577657.html
Copyright © 2020-2023  润新知