Python 自动化接单实战(六):动态网页流程如何保存登录态与失败证据
2026/7/29 18:53:17 网站建设 项目流程

本篇复用上一篇sync.pyget_json()sync.db:先查询数据库中未完成的order_id,仅把 API 无法覆盖的授权动作交给browser_flow.py,下载结果再以同一业务键回写。上一章的同步库就是本篇任务队列。只有客户拥有页面操作权限时才使用浏览器,凭据不写进源码,也不用固定休眠假装稳定。

一、把登录与业务动作拆开

下面以 Playwright 同步 API 为例。首次由客户在可见浏览器中完成登录,脚本只保存会话状态;状态文件必须加入忽略规则并限制权限。

from__future__importannotationsfrompathlibimportPathfromplaywright.sync_apiimportsync_playwright STATE=Path(".local/session.json")STATE.parent.mkdir(exist_ok=True)defauthorize()->int:try:withsync_playwright()asp:browser=p.chromium.launch(headless=False)context=browser.new_context()page=context.new_page()page.goto("https://example.test/login",wait_until="domcontentloaded")input("完成授权登录后按回车:")context.storage_state(path=str(STATE))browser.close()exceptExceptionasexc:print(f"authorize_failed type={type(exc).__name__}")return2STATE.chmod(0o600)print(f"state_saved path={STATE}")return0if__name__=="__main__":raiseSystemExit(authorize())

运行输出:

state_saved path=.local/session.json

业务脚本使用storage_state,若被重定向回登录页就停止并提示重新授权,不在日志中打印 Cookie。

二、等待业务结果而不是等待秒数

importhashlibimportsqlite3withsync_playwright()asp:browser=p.chromium.launch()context=browser.new_context(storage_state=str(STATE))page=context.new_page()withsqlite3.connect("sync.db")asdb:tasks=db.execute("select id from items where export_sha256 is null order by id").fetchall()for(order_id,)intasks:page.goto(f"https://example.test/tasks/{order_id}")withpage.expect_download()aspending:page.get_by_role("button",name="导出").click()target=Path("downloads")/f"{order_id}.pdf"target.parent.mkdir(exist_ok=True)pending.value.save_as(target)digest=hashlib.sha256(target.read_bytes()).hexdigest()db.execute("update items set export_sha256=? where id=?",(digest,order_id))print(f"order_id={order_id}sha256={digest[:12]}")browser.close()

输出示例:

order_id=A-1042 sha256=83da2f4c0a71

三、失败时保留最小证据

为每次任务生成独立目录,只在失败时保存截图、当前 URL、步骤名与脱敏日志。页面结构变化应让定位器明确失败,不要用坐标点击绕过问题。

四、为什么等待条件必须对应业务事实

固定休眠只能说明时间过去了,不能说明导出完成。页面可能在一秒内完成,也可能十秒后仍在排队;固定五秒既浪费快请求,又误判慢请求。expect_response把等待绑定到导出接口,下载场景还可绑定expect_download,最后校验状态码、文件名和内容摘要。等待对象越接近验收事实,偶发失败越少。

登录态文件相当于钥匙,而不是普通缓存。它可能包含 Cookie 和本地存储令牌,所以必须放在版本库外、限制权限、设置有效期并允许客户撤销。脚本检测到重定向登录页时应停止,不能自动尝试未知凭据。记忆点是:浏览器自动化等待证据,不等待秒数;保存钥匙,不保存密码

五、失败证据也有最小化原则

截图、URL、步骤名、业务键和脱敏错误足以定位大多数页面变化。默认保存完整 HTML 可能带入个人信息,录制所有网络请求可能泄漏令牌,因此只有客户授权且确有需要时才扩大证据范围。证据目录按任务键隔离,并为保留期限设置清理规则。

验收时故意让会话过期、按钮改名和导出返回 500,确认三种故障分别落到授权、定位和服务端类别。成功下载的文件摘要回写sync.db,使重复运行跳过已完成业务键。下一篇将读取这张表和浏览器结果,生成确定性的日报任务。

定位器也属于业务契约。优先使用角色、可访问名称或稳定测试属性,因为它们描述“导出按钮”这一语义;易变的层级 CSS 和屏幕坐标只描述当前布局。若页面出现两个同名按钮,代码应缩小到明确区域并断言唯一性,让歧义尽早失败。自动猜第一个元素虽然能暂时运行,却可能在页面改版后操作错误订单。

下载结束后还要验证文件,而不是看到浏览器事件就宣布成功。检查文件非空、扩展名与响应类型匹配,计算摘要并以临时名落盘,最后原子改名。数据库回写放在文件确认之后;进程提前退出时,旧任务仍会重试,摘要则阻止重复文件污染。这样浏览器层继续遵守前几篇建立的“结果可追溯、失败可恢复”契约。


📌 本文把浏览器流程拆成客户授权登录、语义动作和失败证据,避免凭据泄漏与固定休眠带来的不稳定。

💬 你的网页流程更容易卡在登录过期、动态元素、下载文件还是结果确认?

👉 关注《Python 自动化接单实战》,下一篇继续把多个数据源汇总成可定时运行的报告任务。

参考来源

  • Dev.to|6 Open Source Tools That Give You the Web Back
  • Hacker News|Removing React.js and adapting htmx

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询