1. 场景描述
在 RPA 或爬虫中,点击页面上的「导出」按钮时,正常流程是:
- 点击导出 → 站点新开一个临时页面
- 临时页面触发下载 → 关闭自身
- Playwright 捕获
expect_popup
或expect_download
→ 保存文件
但是在 谷歌浏览器(尤其是带安全策略的版本) 中,这种临时下载页有时会被 自动过滤/关闭 。
结果导致:
-
expect_popup()
捕获不到新页面,报错 -
报错信息:
rTarget page, context or browser has been closed
-
文件有时能下,有时完全丢失。
2. 产生原因
- Chrome 将下载跳转页识别为 弹窗,直接拦截关闭。
- 导致 Playwright 监听的新页面「还没来得及挂钩,就被关闭了」。
3. 解决思路
方法一:只监听 expect_download
(推荐)
如果下载操作 不依赖新页面 ,可以只写 expect_download
:
ini
with page.expect_download(timeout=60000) as download_info:
page.get_by_role("button", name="导出").click()
download = download_info.value
download.save_as("保存路径.xlsx")
这样即使 Chrome 把临时页面过滤掉,仍然能捕获下载事件。
方法二:新页面 + 下载双保险
有些网站必须开新页才能下载,这时需要同时监听:
ini
try:
with page.expect_popup() as popup_info:
with page.expect_download(timeout=60000) as download_info:
page.get_by_role("button", name="导出").click()
popup = popup_info.value
download = download_info.value
except Exception as e:
# 如果新页面被 Chrome 过滤,退回到普通下载
with page.expect_download(timeout=60000) as download_info:
page.get_by_role("button", name="导出").click()
download = download_info.value
download.save_as("保存路径.xlsx")
这样即便 新页面被过滤 ,也能退回到 expect_download
兜底。
方法三:优化 Chrome 启动参数
在启动 Chrome 时加上以下参数,减少下载页面被过滤的概率:
python
command = [
r"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe",
r"--remote-debugging-port=9222",
r"--disable-popup-blocking", # 禁用弹窗拦截
r"--no-sandbox",
r"--start-maximized"
]
4. 最佳实践
- 优先使用
expect_download
→ 更稳定。 - 必须新页面时 → 新页监听 + 普通下载兜底。
- 浏览器启动参数优化 → 禁用 popup 拦截。
5. 总结
这个问题的核心是:
- Chrome 自动关闭了下载跳转页
- Playwright 捕获不到新页面,报
Target page closed
- 解决方案是:别依赖新页,用下载事件兜底,或者加启动参数避免拦截。