【代码】Python3|Requests 库怎么继承 Selenium 的 Headers (2024,Chrome)

本文使用的版本:

  • Chrome 124
  • Python 12
  • Selenium 4.19.0

版本过旧可能会出现问题,但只要别差异太大,就可以看本文,因为本文对新老版本都有讲解。

文章目录

    • [1 难点解析和具体思路](#1 难点解析和具体思路)
    • [2 注意事项](#2 注意事项)
      • [2.1 PDF 资源获取时注意事项](#2.1 PDF 资源获取时注意事项)
      • [2.2 Capabilities 写法](#2.2 Capabilities 写法)
      • [2.3 get_log("performance") 写法](#2.3 get_log("performance") 写法)
    • [3 完整代码](#3 完整代码)

1 难点解析和具体思路

这个难点主要是 Chrome 和 Selenium 的版本更新太快了。

首先,如果要继承 Selenium 的 Headers,有两种思路:

  1. 从 Selenium 对于 Chromedriver的参数入手,即 arguments0这样的东西。参考示例代码如下:

    python 复制代码
    # Execute JavaScript to retrieve headers
    headers = driver.execute_script("""
        var headersObj = {};
        var headers = new Map(Object.entries(arguments[0].headers));
        headers.forEach(function(value, key) {
            headersObj[key] = value;
        });
        return headersObj;
    """, driver.execute_script("return window.navigator"))

    具体driver是什么我也不解释了,总之就是这个其实就是个人工配置项,arguments0里根本就不会自带一个headers键值。arguments里面可能存在的所有参数可以看这篇文章:List of Chromium Command Line Switches,https://peter.sh/experiments/chromium-command-line-switches/

  2. 从 Selenium 抓的包入手,即使用 network 相关的,在 Selenium 里面是 get_log("performance")。这个方式在 Selenium 4.10 之后有所改变,具体改变见下文。

2 注意事项

我这篇文章需要继承 headers 是因为网络上有些资源是需要登录注册的,但是每次都自己重新获取 Cookie 是很麻烦的。我这里以一个随便找的 PDF 资源(https://www.sigmaaldrich.cn/CN/zh/sds/aldrich/488488)的获取为例。

2.1 PDF 资源获取时注意事项

具体可以看【记录】Python|Selenium 下载 PDF 不预览不弹窗(2024年),代码的解释也写了,这部分就不展开说了,本文的最后面贴了完整的代码。

2.2 Capabilities 写法

参考:How to Capture Network Traffic When Scraping with Selenium & Python

在 Chrome 75 之后这部分出现了改变。Chrome 和 chromedriver 的版本很重要。版本 75 左右的日志记录功能发生了变化,以适应 W3C 合规性。如果您卡在 Chrome/chromedriver 版本 75 以下,则需要在下面的第一个代码片段中使用loggingPrefs而不是goog:loggingPrefs。

python 复制代码
caps = DesiredCapabilities.CHROME
# capabilities["loggingPrefs"] = {"performance": "ALL"}  # chromedriver < ~75
caps['goog:loggingPrefs'] = {'performance': 'ALL'}

2.3 get_log("performance") 写法

参考:Getting TypeError: WebDriver.init() got an unexpected keyword argument 'desired_capabilities' when using Appium with Selenium 4.10-Stackoverflow

在 Selenium 4.10 之后这部分出现了改变。

Selenium 4.10 之前:

python 复制代码
driver = webdriver.Chrome(service=s, options=options, desired_capabilities=caps) # selenium < 4.10

Selenium 4.10 之后:

python 复制代码
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
driver = webdriver.Chrome(service=s, options=options)

3 完整代码

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

caps = DesiredCapabilities.CHROME
# capabilities["loggingPrefs"] = {"performance": "ALL"}  # chromedriver < ~75
caps['goog:loggingPrefs'] = {'performance': 'ALL'}

options = Options()
# options.add_argument(
#     "user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'")  # UA
# options.add_argument("user-data-dir=C:/Users/User/AppData/Local/Google/Chrome/User Data/Default")
s = Service("D:/software/chromedriver.exe")
# Disable the built-in PDF viewer
options.add_experimental_option('prefs', {
    "download.prompt_for_download": True,
    'plugins.always_open_pdf_externally': False
    })
# desired_capabilities has been removed according to this post,so the newest way looks like this : options = webdriver.ChromeOptions() options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
# driver = webdriver.Chrome(service=s, options=options, desired_capabilities=caps) # selenium < 4.10
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
driver = webdriver.Chrome(service=s, options=options)


pdf_url = 'https://www.sigmaaldrich.cn/CN/zh/sds/aldrich/488488'

# get driver log
driver.get(pdf_url)
print(driver.log_types)
network_logs = driver.get_log("performance")

import json
# Extract headers from the network logs
headers = {}
for log in network_logs:
    log_message = json.loads(log['message'])['message']  # Parse log message as JSON
    if 'params' in log_message and 'request' in log_message['params']:
        request_params = log_message['params']['request']
        if 'headers' in request_params:
            headers = request_params['headers']
            break  # Exit loop after finding headers

import requests

# Use requests to download the PDF file with headers
response = requests.get(pdf_url, headers=headers)

# Check if the request was successful
if response.status_code == 200:
    # Save the PDF file
    with open("output.pdf", "wb") as f:
        f.write(response.content)
    print("PDF file downloaded successfully.")
else:
    print("Failed to download the PDF file.")

# Close the Selenium WebDriver
driver.quit()

这样子写代码就不需要 Selenium 去 sleep 等待下载了,也可以很好地解决一部分 Requests 库的反爬虫问题,不过对于防止重放攻击的反爬虫手段还是无效。

本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/137891147。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

相关推荐
笨鸟先飞,勤能补拙2 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能3 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂3 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study4 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境4 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境4 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1234 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102165 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb005 小时前
一个项目带你入门AI应用开发01
python
0566466 小时前
Python康复训练——常用标准库
开发语言·python·学习