1. 破解iframe嵌套难题从页面结构分析到实战定位第一次用Selenium爬取某网专利数据时我盯着浏览器调试工具里的iframe标签发了半小时呆。这个看似普通的框架嵌套让我的爬虫代码完全抓不到数据——就像隔着玻璃窗拿不到柜台里的商品。后来才发现现代网页为了防止恶意爬取越来越喜欢用iframe封装核心数据区域。具体到这个专利网站检索结果被放在id为iframeResult的框架里。直接使用常规的xpath定位会发现元素根本不存在因为主页面和iframe属于不同的文档上下文。这里有个关键技巧必须先切换到iframe上下文才能操作内部元素。代码中这行driver.switch_to.frame(iframe)就是解决问题的钥匙。但实际操作中还会遇到两个坑切换iframe后如果还要操作主页元素必须用driver.switch_to.default_content()切回主文档部分动态加载的iframe需要显式等待我用的是最朴素的time.sleep(3)专业点可以用WebDriverWait# 典型iframe处理流程示例 iframe driver.find_element(xpath,//*[idiframeResult]) driver.switch_to.frame(iframe) # 进入iframe上下文 # 这里才能正常定位iframe内部元素 data driver.find_elements(By.CLASS_NAME,fz14) driver.switch_to.default_content() # 操作完切回主文档2. 突破300页数据限制时间分片策略详解这个专利网站的设计很贴心——单次检索最多只返回300页数据。当我需要爬取1992-2023年的全部专利时这个限制就像给马拉松选手设置了100米的跑道。经过反复测试发现可以通过细分时间区间来绕过限制。我的解决方案是把大时间范围切成若干个小段。比如1992-2023年按周切割每次只查询7天的数据。这里有个细节时间输入框不能用常规的send_keys()方法必须用JavaScript直接赋值。因为该网站的前端做了特殊处理常规输入会触发验证机制。# 时间分片输入示例 start_date driver.find_element(id,publishdate_from) end_date driver.find_element(id,publishdate_to) driver.execute_script(arguments[0].value 1992-05-16, start_date) driver.execute_script(arguments[0].value 1992-05-23, end_date) # 每次只查7天 search_btn driver.find_element(By.CLASS_NAME,buttOther) search_btn.click()实际项目中还需要处理日期边界条件遇到节假日可能没有数据早期专利数量少可以适当扩大时间间隔最好记录每次成功抓取的时间段方便断点续爬3. 无URL翻页的逆向工程模拟人工操作的精髓最让我头疼的是这个网站的翻页机制——点击下一页按钮后URL居然不变这意味着既不能用简单的循环递增页码参数也不能通过URL直接跳转到指定页面。经过抓包分析发现翻页动作是通过前端JavaScript处理的根本没有传统意义上的分页参数。解决方案是完全模拟人工操作先定位当前页码元素确认位置找到下一页按钮的xpath注意第一页和其他页的按钮位置不同加入异常处理防止翻页失败# 翻页处理代码片段 if flag 1: # 第一页下一页按钮位置特殊 next_btn driver.find_element(xpath,//*[idctl00]/table/tbody/tr[3]/td/table/tbody/tr/td/div/a[9]) else: next_btn driver.find_element(xpath,//*[idctl00]/table/tbody/tr[3]/td/table/tbody/tr/td/div/a[11]) next_btn.click() time.sleep(2) # 必须留足页面加载时间为了提高稳定性我还添加了这些措施每翻10页就检查一次当前页码网络波动时自动重试3次记录最后成功页码到本地文件4. 验证码攻防战从手动识别到自动破解当爬虫运行到第15页时突然跳出验证码——这个网站的反爬机制比预想的更灵敏。更麻烦的是验证码元素时有时无用常规的find_element经常会报错。经过反复试验总结出这套组合拳首先用显式等待确保验证码加载完成然后通过截图OCR识别。这里推荐ddddocr库对扭曲文字识别率很高。但要注意网站验证码通常区分大小写需要统一转大写提交。def handle_captcha(driver): try: # 先滚动到验证码区域 element driver.find_element(xpath,/html/body) driver.execute_script(return arguments[0].scrollIntoView(true);,element) # 验证码识别流程 img driver.find_element(xpath, //*[idCheckCodeImg]) img.screenshot(captcha.png) with open(captcha.png, rb) as f: ocr ddddocr.DdddOcr() captcha ocr.classification(f.read()).upper() # 输入并提交 input driver.find_element(id,CheckCode) button driver.find_element(xpath,/html/body/p[1]/input[2]) driver.execute_script(farguments[0].value {captcha}, input) button.click() return True except Exception as e: print(f验证码处理失败: {str(e)}) return False实战中发现几个关键点验证码出现频率与访问速度正相关控制在3秒/页基本不会触发识别错误时要能自动重试但连续失败3次最好暂停1小时可以预先收集100个验证码样本测试识别准确率5. 数据持久化优化从内存泄漏到高效存储当爬取数据量达到万级时最初的代码开始频繁崩溃。排查发现是内存泄漏问题——每次循环都没有及时释放DOM对象。优化后的方案采用流式处理每爬取20条立即存入CSV使用pandas的追加模式避免内存堆积为每个时间分段创建单独文件# 优化后的存储方案 def save_data(data_list, filename): df pd.DataFrame(data_list) # modea表示追加写入headerFalse避免重复标题 df.to_csv(filename, modea, indexFalse, headerFalse, encodinggb18030) data_list.clear() # 及时清空内存 # 在主循环中每处理完一页就保存 if len(data_list) 20: save_data(data_list, patent_data.csv)其他存储优化技巧使用with语句自动关闭文件定期备份已爬取的数据添加数据去重机制对大数据量考虑使用数据库替代CSV6. 反反爬策略大全如何优雅地长期运行要让爬虫稳定运行数周必须处理好这些细节请求频率控制随机延时time.sleep(random.uniform(1, 3))工作日白天放慢速度遇到验证码后自动降速请求头伪装headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Referer: https://original.site.domain, Accept-Language: zh-CN,zh;q0.9 }异常处理体系网络异常自动重试页面结构变化自动报警验证码连续失败转人工日志监控系统记录每个请求的状态统计每日成功/失败数量关键操作微信通知# 典型的异常处理结构 try: # 爬取操作 except ElementNotInteractableException: driver.refresh() time.sleep(5) except TimeoutException: reset_proxy() except Exception as e: send_alert(f未知异常: {str(e)})7. 效率提升技巧从单线程到分布式当需要爬取百万级数据时我逐步优化出了这套方案基础优化复用浏览器实例避免频繁启动并行处理验证码识别预处理xpath选择器进阶方案# 使用多进程加速 from multiprocessing import Pool def crawl_task(date_range): # 每个进程处理一个时间片段 driver init_driver() # 独立实例 # ...爬取逻辑... driver.quit() if __name__ __main__: date_ranges split_date_range(1992-01-01, 2023-12-31, 365) # 按年分割 with Pool(4) as p: # 4进程并行 p.map(crawl_task, date_ranges)终极方案使用ScrapySelenium组合搭建Redis任务队列分布式部署到多台服务器自动扩缩容机制不过要注意分布式爬虫必须更加谨慎地控制请求频率否则很容易触发网站的风控机制。建议先小规模测试逐步增加并发量。