为何Selenium webdriver可打开Python标准库urlopen无法访问的URL?
原因分析
- 请求头标识差异
urllib 默认发送的请求头中User-Agent字段为Python-urllib/3.x格式,会被雅虎的反爬虫系统直接识别为非浏览器请求,针对部分风控等级较高的深层页面直接返回404错误。而Selenium驱动的Chrome浏览器会携带和普通用户完全一致的浏览器UA、Accept、Accept-Language等标准请求头,不会被基础反爬规则拦截。 - 会话上下文校验不通过
雅虎财经的期权页面要求访问者持有前置页面(雅虎主页、对应股票详情页)生成的有效Cookie、会话标识,你直接用urllib发起孤立请求,没有携带对应的会话信息,服务端判定请求非法就返回404。Selenium模拟的是完整浏览器运行环境,会自动存储、传递不同页面间的Cookie,会话链路符合服务端的校验规则。 - 客户端特征识别拦截
部分高级反爬规则会校验请求的TLS握手指纹、客户端JS运行环境特征,urllib的TLS指纹和真实Chrome差异极大,很容易被特征库匹配识别。Selenium驱动的Chrome本身就是真实浏览器,所有客户端特征都和普通用户访问一致,可以绕过这类校验。
临时修复方案
你可以给urllib手动添加真实浏览器的请求头、补充Cookie信息,就能正常访问对应页面,示例代码如下:
from urllib.request import urlopen, HTTPError, Request url = "https://finance.yahoo.com/quote/IWM/options?p=IWM&straddle=false&date=1640908800" # 替换为你本地Chrome浏览器的真实User-Agent headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } try: req = Request(url, headers=headers) with urlopen(req) as f: lines = f.readlines() print(f"retrieved {len(lines)} lines.") except HTTPError as e: print(e)
内容的提问来源于stack exchange,提问作者John Ladasky
相关产品推荐
相关产品推荐

