fix: 全面增强 SSL 证书错误处理和弹窗监控

- 添加 --ignore-certificate-errors 浏览器级参数
- 注册 popup 事件处理器,监控导出触发的弹窗
- 弹窗出现时自动绕过 SSL 拦截
- 失败时遍历所有页面(主页面+弹窗+新标签页)进行 SSL 绕过和下载重试

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 18:58:06 +08:00
parent 70f293db96
commit c6f81b6f6e
+35 -10
View File
@@ -50,7 +50,8 @@ class SecsionDownloader:
args=[ args=[
"--disable-dev-shm-usage", "--disable-dev-shm-usage",
"--disable-gpu", "--disable-gpu",
"--no-sandbox" "--no-sandbox",
"--ignore-certificate-errors"
] ]
) )
context = await browser.new_context( context = await browser.new_context(
@@ -191,6 +192,18 @@ class SecsionDownloader:
page.on("response", on_response) page.on("response", on_response)
# 监控弹窗(导出可能在新窗口打开下载链接)
popup_pages = []
async def handle_popup(popup):
popup_pages.append(popup)
logger.info(f"检测到弹窗: {popup.url}")
# 弹窗的 SSL 拦截也要处理
await popup.wait_for_load_state("domcontentloaded", timeout=15000)
await self._bypass_ssl_interstitial(popup)
page.on("popup", handle_popup)
# 记录下载目录现有文件(用于兜底检测) # 记录下载目录现有文件(用于兜底检测)
existing_files = set(os.listdir(self.download_dir)) if os.path.exists(self.download_dir) else set() existing_files = set(os.listdir(self.download_dir)) if os.path.exists(self.download_dir) else set()
@@ -203,9 +216,16 @@ class SecsionDownloader:
await export_btn.click() await export_btn.click()
logger.info("等待文件下载中...") logger.info("等待文件下载中...")
# 点击导出后,可能弹出 SSL 证书过期拦截页面 # 等待弹窗出现
await asyncio.sleep(2)
# 先处理主页面 SSL 拦截
await self._bypass_ssl_interstitial(page) await self._bypass_ssl_interstitial(page)
# 再处理所有弹窗
for popup in popup_pages:
await self._bypass_ssl_interstitial(popup)
download = await download_info.value download = await download_info.value
filename = download.suggested_filename filename = download.suggested_filename
save_path = os.path.join(self.download_dir, filename) save_path = os.path.join(self.download_dir, filename)
@@ -214,24 +234,29 @@ class SecsionDownloader:
return save_path return save_path
except Exception as download_err: except Exception as download_err:
# Playwright download 事件未触发,尝试 SSL 绕过后再等
logger.warning(f"Playwright 下载事件捕获失败: {download_err}") logger.warning(f"Playwright 下载事件捕获失败: {download_err}")
# 二次尝试:可能 SSL 页面刚出现,再尝试绕过 # 处理所有已知页面的 SSL 拦截
bypassed = await self._bypass_ssl_interstitial(page) all_pages = [page] + popup_pages + [p for p in page.context.pages if p != page]
if bypassed: for p in all_pages:
logger.info("SSL 拦截已绕过,等待下载...")
try: try:
async with page.expect_download(timeout=30000) as dl_info: await self._bypass_ssl_interstitial(p)
except Exception:
pass
# 绕过 SSL 后重新等待下载
for p in all_pages:
try:
async with p.expect_download(timeout=15000) as dl_info:
pass pass
download = await dl_info.value download = await dl_info.value
filename = download.suggested_filename filename = download.suggested_filename
save_path = os.path.join(self.download_dir, filename) save_path = os.path.join(self.download_dir, filename)
await download.save_as(save_path) await download.save_as(save_path)
logger.info(f"SSL 绕过后下载成功: {save_path}") logger.info(f"SSL 绕过后从页面下载成功: {save_path}")
return save_path return save_path
except Exception: except Exception:
logger.warning("SSL 绕过后仍未触发下载事件") continue
logger.info("尝试文件系统兜底检测...") logger.info("尝试文件系统兜底检测...")