Python爬虫进阶:Playwright请求拦截(Request Interception)与动态代理IP实战

发布时间:2026/6/24 9:47:14

Python爬虫进阶:Playwright请求拦截(Request Interception)与动态代理IP实战 前言大家好在日常的爬虫开发和自动化抓取中我们经常会遇到一些让人头疼的场景。比如目标网站加载了大量无关的图片和视频拖慢了抓取速度或者通过检测请求头和前端特征来封禁我们的机器。今天我们就来深入探讨一下 Playwright 的一项高级杀手锏——请求拦截Request Interception并结合爬虫代理实现高效、高并发、防屏蔽的工业级爬虫。一、 为什么我们需要请求拦截在实际的爬虫抓取场景中我们经常会面临以下痛点资源浪费目标网站请求了额外的静态资源如图片、CSS、大字体文件严重拖慢了页面加载速度浪费了宝贵的带宽。认证与状态管理登录态 token 藏在请求头里需要在每次请求发送前动态注入。代理动态切换使用代理 IP 抓取时需要考虑代理认证信息如何正确附加以及如何强制隧道代理切换 IP。绕过前端反爬前端包含大量探针如 navigator.webdriver如果不在请求层面或加载前拦截极易被识别。这些问题的核心诉求就是在请求发出去之前或响应回来之前能够拦截并修改它。二、 Playwright 请求拦截的核心机制Playwright 实现请求拦截主要依赖两个核心对象RouteRoute 对象代表一个待处理的请求它赋予了我们控制请求后续走向的权力常见的方法有放行 continue()、伪造响应 fulfill() 以及直接中断 abort()。RequestRequest 对象代表已发出或正在发出的请求我们可以从中读取关键的上下文信息例如通过 url()、headers()、method() 获取请求详情。当页面触发网络请求时只要我们通过 page.route(url, handler) 注册了对应 URL 模式的拦截器Playwright 就会把 Route 对象交给我们处理。请注意在处理函数中必须调用 continue()、fulfill() 或 abort() 三者之一来结束拦截否则请求会一直挂起continue()fulfill()abort()。三、 实战结合爬虫代理实现请求拦截与特征抹除下面是一套综合实战代码。我们将演示如何配置全局隧道代理、如何通过拦截器丢弃无用静态资源、如何动态切换代理 IP以及如何抹除自动化工具特征。importasyncioimportuuidimportosfromplaywright.async_apiimportasync_playwright,Route,Request# 亿牛云爬虫代理配置信息 (请替换为您自己的专属信息)PROXY_HOSTt.16yun.cnPROXY_PORT31111PROXY_USERyour_usernamePROXY_PASSyour_passwordasyncdefmock_static_handler(route:Route,request:Request): 静态资源拦截器提高页面加载速度 urlrequest.url.lower()# 拦截图片资源并中止请求极大提升抓取效率ifurl.endswith(.png)orurl.endswith(.jpg):awaitroute.abort()## 字体文件直接跳过减少加载时间elifurl.endswith(.woff2):awaitroute.abort()#else:# 非目标请求继续正常流程awaitroute.continue_()#asyncdefcontrolled_ip_handler(route:Route,request:Request): 代理 IP 动态切换拦截器通过附加 Proxy-Tunnel 头部实现 # 每次请求生成新的 UUID 作为 tunnel 值触发亿牛云强制分配新出口 IPtunnel_idstr(uuid.uuid4())## 动态注入自定义请求头并将原请求头合并awaitroute.continue_(headers{**request.headers,Proxy-Tunnel:tunnel_id,#User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36#})asyncdefmain():asyncwithasync_playwright()asp:# 1. 启动浏览器并配置全局代理# 注意proxy.server 格式必须是 http://host:portPlaywright不支持https前缀的代理browserawaitp.chromium.launch(headlessTrue,proxy{server:fhttp://{PROXY_HOST}:{PROXY_PORT},#username:PROXY_USER,#password:PROXY_PASS,#})# 忽略HTTPS证书错误这在国内服务器代理环境中非常实用contextawaitbrowser.new_context(ignore_https_errorsTrue)#pageawaitcontext.new_page()# 2. 全局注入页面加载前执行清除 webdriver 标识绕过常规反爬awaitcontext.add_init_script( Object.defineProperty(navigator, webdriver, {get: () undefined}); window.webdriver undefined; delete window.CallSelenium; )## 3. 注册请求拦截器# 注意page.route() 注册的拦截器按顺序匹配第一个匹配的拦截器处理后后续不再调用# 拦截所有API请求实现动态代理IP切换awaitpage.route(**/api/**,controlled_ip_handler)# 拦截所有其他请求过滤无用静态资源awaitpage.route(**/*,mock_static_handler)try:# 4. 执行抓取动作 (以httpbin为例验证IP和Header)print(正在访问目标网站...)awaitpage.goto(https://httpbin.org/ip)# 等待网络空闲awaitpage.wait_for_load_state(networkidle)#contentawaitpage.content()print(抓取成功页面返回的IP信息:,content[:500])exceptExceptionase:print(f抓取发生异常:{e})finally:awaitbrowser.close()if__name____main__:asyncio.run(main())四、 避坑与注意事项在实际开发中关于 Request Interception 有几个关键细节需要大家注意拦截器的链式冲突上面代码提到了Playwright 的拦截器是匹配即止的。如果你的一个请求同时命中了静态资源匹配和 API 匹配只有先注册/先命中的会被执行。如果需要链式处理建议在一个 handler 里整合逻辑。异常捕获如果拦截器抛出异常且未被捕获Playwright 会默认放行该请求。在工业级爬虫里建议给 Handler 加上 try/except异常时主动 await route.abort(“failed”) 防止真实 IP 或特征泄露。代理排查如果抓取时发现 IP 还是本机或者报错连不上快速检查下配置格式是否带有 http:// 前缀或者直接用 curl -x “http://username:passwordt.16yun.cn:31111” -k https://httpbin.org/ip 测试一下代理服务的连通性。总结掌握 Playwright 的请求拦截就像是给爬虫装上了“透视眼”和“手术刀”。结合高质量的代理IP我们不仅能在网络层做到无缝伪装还能大幅优化抓取性能降低带宽成本。如果你在爬虫架构设计或 Playwright 部署上有什么问题欢迎在评论区留言交流。我们下期技术干货再见

相关新闻