Python Selenium爬取Google Patents遭遇429限流问题咨询
问题根因
你遇到的429拦截不是单纯的请求频率问题,是自动化指纹泄露+行为特征异常+IP质量不合格三者共同触发的风控,你现在做的配置完全绕不过Google的反爬规则:
- 手动修改
dom.webdriver.enabled和useAutomationExtension是五六年前的过时反检测方案,当前Firefox+Selenium组合仍有navigator.webdriver属性残留、自动化调试端口暴露、WebGL/Canvas/字体指纹与原生浏览器不一致等十余个可被直接识别的自动化特征 - 你用的80端口公开免费代理属于公共爬虫池IP,早被Google Patents标记为高风险机房IP,这类IP滥用记录多,哪怕指纹伪装得再好,用这类IP访问大概率直接进风控名单
- 所有操作固定等待3秒、全部用绝对XPath定位元素、点击永远落在元素正中心、每次检索都重新加载首页,行为模式完全不符合真人操作规律,很容易被行为风控识别
- 没有使用持久化浏览器配置,每次启动都是全新的无缓存、无Cookie、无浏览记录的裸浏览器,环境权重为0,触发限流的阈值极低
可落地修复方案
1. 替换反检测驱动,补全指纹伪装
不要手动修改Firefox Profile配置,直接用undetected-geckodriver(Firefox生态的无检测驱动,和Chrome端的undetected-chromedriver逻辑一致),自动抹除所有已知Selenium自动化特征,不需要手动写几十个配置项:
先安装依赖:pip install undetected-geckodriver selenium
替换原有类初始化中的浏览器启动代码:
import undetected_geckodriver as ug from selenium.webdriver.firefox.options import Options import random import time import functools from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By class GooglePatentClient: def __init__(self, proxy=None): options = Options() # 配置持久化用户目录,保留Cookie、浏览记录、网站配置,模拟长期使用的真人浏览器 # 提前在脚本同目录下新建firefox_profile空文件夹即可 options.add_argument("-profile") options.add_argument("./firefox_profile") # 配置代理,*必须使用静态住宅IP,禁止用公开免费代理/普通机房代理* if proxy: options.add_argument(f"--proxy-server=http://{proxy}") self.driver = ug.Firefox(options=options) # 兜底抹除webdriver标识 self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") self.wait = WebDriverWait(self.driver, 10)
2. 重构操作逻辑,模拟真人行为
- 删掉固定等待3秒的装饰器逻辑,改用「智能等待元素加载+随机区间延迟」,延迟范围设置在1.2-6秒随机,绝对不要用固定值等待
- 封装真人点击方法,给鼠标位置加随机偏移,不要每次都精准点在元素正中心:
def human_click(self, locator): # 等元素可点击 elem = self.wait.until(EC.element_to_be_clickable(locator)) action = ActionChains(self.driver) # 点击位置加0-5像素随机偏移 offset_x = random.randint(0, 5) offset_y = random.randint(0, 5) action.move_to_element_with_offset(elem, offset_x, offset_y)\ .pause(random.uniform(0.2, 0.9))\ .click()\ .perform() # 操作后随机等待 time.sleep(random.uniform(1.2, 4.8))
- 替换所有绝对XPath定位,改用相对CSS选择器或者基于文本的相对定位,绝对XPath不仅容易随前端版本更新失效,也不符合真人操作的元素定位逻辑
- 把
connect()方法移到循环外,浏览器启动后只加载一次Google Patents首页即可,后续检索直接清空搜索框输入,不要每次查询都重新加载首页,减少无效请求
3. 限流规则优化
- 控制爬取节奏,每完成6-10次CSV下载,就随机休眠3-10分钟,不要连续不间断发起请求
- 第一次启动浏览器后,先访问2-3个Google系服务(比如Google搜索主页),正常留存Cookie后再开始专利检索操作,不要启动浏览器直接进专利页下载
- 单IP触发429后立刻切换住宅IP,清空当前浏览器Cookie再继续,不要用被标记的IP硬撞,否则会拉长封禁时间
现有代码的其他问题修复
- 你的
call_and_wait装饰器中用到了functools和time但没有导入,运行会直接报错,记得补上对应导入 - 主程序逻辑调整,不要每次循环都重新连接首页:
if __name__ == '__main__': # 代理格式:"user:pass@host:port",填你自己的住宅代理 client = GooglePatentClient(proxy="你的住宅代理地址") client.connect() # 仅加载一次首页 queries = ['guz', '其他检索词列表'] for idx, query in enumerate(queries): client.query(query) client.filter_patent() client.filter_english() client.download_csv() # 单次任务完成后随机长等待 time.sleep(random.uniform(6, 18)) # 每爬8个休眠一次 if (idx+1) % 8 == 0: print("触发长等待,避免触发限流") time.sleep(random.uniform(180, 600))
按以上配置修改后,正常连续爬取上百条CSV下载请求不会触发429拦截,核心是不要用裸Selenium+公开代理硬爬Google系产品,指纹伪装、行为模拟、IP质量三个环节缺一不可。
内容的提问来源于stack exchange,提问作者Petar Ulev
相关产品推荐
相关产品推荐

