You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Selenium WebDriver获取与requests一致的网页响应?

问题描述

原本基于requests的代码可正常运行:

response = requests.get(url).text
soup = BeautifulSoup(response, 'html.parser')

替换为Selenium WebDriver实现后:

driver = web_driver()
response = driver.page_source
soup = BeautifulSoup(response, 'html.parser')

两者获取的响应存在差异,导致后续代码报错。想知道:

  1. 是否有办法让Selenium WebDriver获取与requests完全一致的响应?
  2. 若可行,是否存在适配所有URL的通用方案?

使用示例:在从URL https://int.soccerway.com/teams/egypt/pharco/38185/squad/ 的表格生成Pandas DataFrame的场景中,requests与Selenium读取元素的结果不同。


解决方案

差异根源

requests直接获取服务器返回的原始HTML响应,而Selenium的page_source是浏览器渲染完成后的DOM结构——这其中可能包含JS动态生成的内容,同时部分网站会根据请求的客户端特征(如User-Agent、是否为自动化浏览器)返回不同内容,导致两者结果不一致。

让Selenium贴近requests行为的方法

1. 完全模拟requests的请求特征

同步requests的请求头、Cookie,甚至禁用JavaScript,让Selenium的请求行为尽可能贴近requests:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

# 从requests请求中复制完整请求头(可通过requests.get(url).request.headers获取)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    # 按需添加其他headers字段
}

chrome_options = Options()
# 设置User-Agent
chrome_options.add_argument(f"user-agent={headers['User-Agent']}")
# 禁用JavaScript,避免动态渲染
chrome_options.add_argument("--disable-javascript")
# 隐藏Selenium自动化标识
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)

driver = webdriver.Chrome(options=chrome_options)
driver.get(url)

# 若requests有登录态Cookie,同步到Selenium
# for name, value in requests_cookies.items():
#     driver.add_cookie({"name": name, "value": value, "domain": ".soccerway.com"})
# driver.refresh()

response = driver.page_source
soup = BeautifulSoup(response, 'html.parser')

driver.quit()

2. 通过CDP获取原始HTTP响应

利用Chrome DevTools协议直接抓取服务器返回的原始HTML,绕过浏览器渲染,这是最接近requests的方式:

from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
# 启用网络监听
driver.execute_cdp_cmd("Network.enable", {})
# 拦截文档类型请求
driver.execute_cdp_cmd("Network.setRequestInterception", {
    "patterns": [{"urlPattern": "*", "resourceType": "Document", "interceptionStage": "HeadersReceived"}]
})

raw_response = None

def capture_response(event):
    global raw_response
    # 获取响应体
    body = driver.execute_cdp_cmd("Network.getResponseBody", {"requestId": event["requestId"]})
    raw_response = body["body"]
    # 放行请求
    driver.execute_cdp_cmd("Network.continueInterceptedRequest", {"requestId": event["requestId"]})

driver.add_event_listener("Network.responseReceived", capture_response)

driver.get(url)

# 处理压缩响应(若返回内容是gzip格式)
# import gzip
# raw_response = gzip.decompress(raw_response).decode('utf-8')

soup = BeautifulSoup(raw_response, 'html.parser')
driver.quit()

通用方案的局限性

不存在适配所有URL的完美方案:

  • 部分网站会通过Canvas/WebGL指纹等复杂检测识别自动化工具,此时需用undetected-chromedriver等库隐藏Selenium特征。
  • 如果网站核心内容完全依赖JS动态生成,requests无法获取这些内容,此时Selenium的page_source必然与requests响应不同,这种场景下无法让两者一致。

内容的提问来源于stack exchange,提问作者Digital Farmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:07