如何为Playwright-Python测试缓存Chromium有头模式交互实现离线测试?
实现Playwright-Python有头模式下的HTTP请求缓存(CI离线测试)
针对你的需求,这里提供两种可靠的实现方案,适配playwright-python>=1.41的有头模式场景:
方案一:利用Chromium原生缓存目录 + CI缓存
通过指定Chromium的用户数据目录存储缓存,结合CI的缓存机制复用该目录,再通过启动参数强制离线使用缓存。
代码实现
首次运行(录制缓存)
from playwright.sync_api import sync_playwright with sync_playwright() as p: # 指定缓存目录,可自定义路径 browser = p.chromium.launch( headless=False, user_data_dir="./chromium_cache" ) context = browser.new_context() page = context.new_page() # 执行你的网页抓取逻辑 page.goto("https://target-site.com") # ...其他操作(如点击、表单提交等) browser.close()
后续运行(离线使用缓存)
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch( headless=False, user_data_dir="./chromium_cache", args=["--offline"] # 强制浏览器使用缓存,禁止发起真实HTTP请求 ) context = browser.new_context() page = context.new_page() # 执行抓取逻辑,所有请求将读取本地缓存 page.goto("https://target-site.com") # ...其他操作 browser.close()
CI缓存配置示例(以GitHub Actions为例)
在你的CI workflow中添加缓存步骤,保存Chromium缓存目录:
- name: Cache Chromium Cache Directory uses: actions/cache@v3 with: path: ./chromium_cache key: ${{ runner.os }}-chromium-cache-${{ hashFiles('your-scraper-script.py') }} restore-keys: | ${{ runner.os }}-chromium-cache-
注意事项
--offline参数会让浏览器完全离线,无缓存的请求会直接失败;若需允许 fallback 到网络,可移除该参数(浏览器会优先使用缓存)。- 用户数据目录包含缓存、Cookies、LocalStorage等所有浏览器状态,若仅需缓存HTTP请求,可结合Chromium的
--disk-cache-dir参数单独指定缓存路径(需额外配置)。
方案二:使用HAR文件录制/重放请求
通过Playwright的HAR(HTTP Archive)功能录制所有请求响应,后续运行时通过请求拦截从HAR文件读取缓存内容,实现精准的请求复用。
代码实现
首次运行(录制HAR文件)
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=False) # 录制所有请求到HAR文件,mode="full"包含静态资源 context = browser.new_context( record_har_path="./request_cache.har", record_har_mode="full" ) page = context.new_page() # 执行抓取逻辑 page.goto("https://target-site.com") # ...其他操作 context.close() # 关闭上下文时自动写入HAR文件 browser.close()
后续运行(重放HAR缓存)
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=False) # 开启离线模式,确保不走网络 context = browser.new_context(offline=True) # 加载HAR文件,拦截所有请求并返回缓存响应 with open("./request_cache.har", "r", encoding="utf-8") as f: har_content = f.read() def handle_route(route): # 从HAR中匹配对应请求的响应 route.fulfill_from_har(har_content, url=route.request.url) context.route("**/*", handle_route) page = context.new_page() # 执行抓取逻辑,请求将从HAR获取响应 page.goto("https://target-site.com") # ...其他操作 browser.close()
注意事项
- 可通过
record_har_url_filter参数过滤需要录制的请求(如仅录制特定域名),减少HAR文件体积。 - 若需要匹配动态参数的请求,可调整
fulfill_from_har的匹配规则(如使用url_pattern替代精确URL匹配)。
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 原生缓存目录 | 实现简单,无需修改核心业务逻辑,保留完整浏览器状态 | 缓存目录体积较大,包含无关用户数据,缓存规则由浏览器控制 |
| HAR录制/重放 | 精准控制缓存内容,可编辑HAR文件,体积更小 | 需额外处理HAR录制和路由拦截逻辑,复杂场景下需调整匹配规则 |
内容的提问来源于stack exchange,提问作者Intrastellar Explorer
相关产品推荐
相关产品推荐

