ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Playwright 多平台分发:8 个踩坑与合规门禁

Playwright 多平台分发:8 个踩坑与合规门禁 问题与动机我需要一个能把同一篇文章批量发到 10 个技术平台的工具掘金、知乎、CSDN、B站专栏、开源中国、思否、头条号、博客园外加两个 MetaWeblog 协议平台自建 WordPress/Typecho、51CTO。手动复制粘贴一遍就要半小时改个标题得登 10 个后台出错率还高。试过 RSS 同步和 Zapier前者覆盖不了 10 家后者在登录态和富文本编辑器面前直接崩。最后只能自己写Python FastAPI patchrightPlaywright 的社区兼容 fork在 Windows 国内网络环境下用于浏览器自动化 Vue3 前端 SQLite 队列。核心诉求不是“能发”而是稳定——平台改版只改适配器不重构主流程登录一次长期复用AI 生成的内容必须过门禁才放行。架构四层隔离故障不扩散整套系统分四层每层职责单一适配器层每个平台一个适配器声明needs_browser、login_url、home_url、key_selectors、selector_version以及check_auth/whoami/publish/update四个方法。平台改版时只改这个文件上层任务调度、门禁、队列完全不动。浏览器层patchright 驱动持久化 profile 目录。本文用的浏览器自动化库是 Playwright 的社区兼容 fork包名 patchright下文提到「Playwright」时指其 API 形态实际调用的是 patchright选它是因为在 Windows 国内网络环境下对已装浏览器兼容性更好与对抗性反检测无关。登录一次后 cookie 落在磁盘后续任务复用。坑profile 目录被占用会直接抛ProcessSingleton错误所以登录前必须先释放池内所有实例否则新起浏览器就是报错。门禁层四道闸门——高危词安全扫描 → AIGC 显式标识注入 → 双模型二审配了REVIEW_MODEL走 LLM没配降级本地启发式→ 发布闸门AI 源文章默认强制草稿人审可用配置开关放开直发。任务层SQLite 队列 任务表支持发布/更新/抓取入库失败留last_error字段方便回看。这个分层不是为了好看。实际跑下来掘金和知乎的 DOM 改动频率不同CSDN 的编辑器是富文本而博客园是纯 Markdown适配器隔离后改一个平台不影响其他 9 个的回归测试。踩坑实录8 个真实故障1. 掘金扫码成功但登录态丢失现象扫码登录成功界面正常但下次启动浏览器又要求重新扫码。排查cookie 没落盘。Chromium 关窗前的 cookie 刷盘时序不稳定正常退出能写异常退出比如超时 kill就丢。修法Python 侧在关窗前主动调export_auth()写storage_state快照并保留关窗前刷新快照的逻辑。不依赖 Chromium 自己的 flush。2. 博客园 MetaWeblog 发布 401现象调blogger.getUsersBlogs返回 401文案是「请配置正确的用户名与访问令牌密码登录已取消」。排查博客园是 MetaWeblog XML-RPC 协议平台 XML-RPC 接口返回的错误文案明确写着『密码登录已取消请在密码框中输入访问令牌』2026-09 实测。令牌需要在 设置→其他设置 里单独创建、默认不存在。页面上要点「创建令牌」才有。我曾把页面标签词 “MetaWeblog” 误当成登录名写进配置排查方法是直接调blogger.getUsersBlogs(, username, token)看返回的 Fault 文案。修法配置里明确区分meta_weblog_username和meta_weblog_token文档里写清令牌生成路径。3. Edge 自动化登录无反应现象用系统 Edge 自动化登录博客园点「登录」按钮毫无反应页面卡死在验证码区域。排查挂 console 监听抓到一条警告Tracking Prevention blocked。Edge 的跟踪防护拦截了o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js的存储访问验证码组件永远不初始化。根因脏的是旧 profile 累积的拦截状态新开的 profile 反而干净。修法登录前清理或新建 profile或者在 Edge 里把该域名加跟踪防护白名单。4. headless 与有头行为不一致现象有头模式下 Angular SPA 渲染正常同一 profile 在 headless 下整页空白0 console 输出。排查headless 模式下 JS 执行时序不同Angular 的 zone.js 在 headless 里没正常初始化。修法改用无头模式 真实鼠标坐标点击mouse.click(x, y)比locator.click()稳定。不追求有头模式统一无头。5. 合成点击不触发 Angular 事件现象locator.click(forceTrue)点在a上Angular 的(click)绑定收不到行内 HTML 完全不变。排查Playwright 的click是合成事件Angular 的事件委托在某些版本下不响应合成事件的isTrusted标志。修法改成在元素上evaluate(el el.click())派发原生事件Angular 能正常接收。6. URL 跳转判断登录状态误判现象未登录时i.cnblogs.com会先跳到account.cnblogs.com/signin再被弹回URL 一度含目标域名导致check_auth误判为已登录。修法不用 URL 判断。改用浏览器上下文的 cookie jar 发独立 HTTP 请求探测后端接口看返回码和 body 里的用户信息。7. 平台选择器是硬契约现象e2e 脚本依赖.vs-btn、.md-editor[contenteditabletrue]、.el-table__row:visible、.acct-card、.el-tabs__item、header.hdr等类名。改样式可以改类名会静默打断所有自动化测试。修法适配器的key_selectors里写死这些选择器并在 CI 里加一步选择器回归测试。类名变更前跑一遍 e2e挂了立刻发现。8. 顶栏在小屏被挤爆现象390px 视口下「新建」按钮越出视口 15pxCJK 文本被逐字竖排。排查根因是没有white-space:nowrap、顶栏没有overflow兜底、全站只有一处 560px 媒体查询。修法给标签文字加nowrap、≤767px 隐藏品牌文字、给顶栏加overflow:hidden兜底并补一个 390/768/1024 三视口的回归测试断言控件包围盒在视口内且文本单行。合规边界使用浏览器自动化发布内容前先确认以下四条约束这是系统内置的红线不是可选配置只自动化自己账号下的内容工具仅操作登录态对应的个人账号不代管他人账号不批量注册账号。遵守各平台服务条款与 robots/频率限制适配器层内置发布间隔与并发上限不绕过平台频率限制不采集其他用户数据。验证码一律走人工接管handoff不自动绕过遇到滑块、图片、短信验证码时暂停任务提示人工介入脚本不尝试解析或伪造验证码。不做批量灌水、不伪造互动数据工具仅用于发布原创或授权转载内容不提供点赞、评论、阅读量等数据伪装功能。配置与代码片段以下三个代码片段来自实际运行环境可直接复制使用。config.json 的 AI/门禁配置片段config.json中门禁与 AI 相关配置如下REVIEW_MODEL为空时降级本地启发式ALLOW_AI_DIRECT_PUBLISH默认false{ai:{REVIEW_MODEL:,ALLOW_AI_DIRECT_PUBLISH:false,aigc_footer:本文由 AI 辅助生成内容基于实测经验整理不构成对任何平台自动化行为的完整描述。,safety_scan:{enabled:true,blocked_terms_file:data/blocked_terms.txt}}}CLI 发稿命令项目根目录下执行--platforms指定目标平台--draft强制走草稿人审--dry-run只跑门禁不实际发布python-mcli publish\--fileblog/cnblogs-xmlrpc.md\--platformscnblogs,wordpress,self-hosted-typecho\--draft\--dry-runPython 调 MetaWeblog 自验片段发布前用blogger.getUsersBlogs验访问令牌是否有效避免 401 进队列后才发现importxmlrpc.client METAWEBLOG_URLhttps://blog园.example/xmlrpc# 替换为实际 MetaWeblog 端点USERNAMEyour_usernameTOKENyour_access_token# 在平台 设置→其他设置 中创建clientxmlrpc.client.ServerProxy(METAWEBLOG_URL,allow_noneTrue)try:blogsclient.weblog.getUsersBlogs(,USERNAME,TOKEN)print(f登录成功账号下有{len(blogs)}个博客)forbinblogs:print(f -{b.get(htmlUrl,unknown)})exceptxmlrpc.client.Faultase:print(f认证失败 (Fault): code{e.code}, message{e.value})raiseSystemExit(1)AI 工程纪律门禁不是摆设写码前先做 Pattern Mining 读邻居代码再写 RED 测试锁行为然后 GREEN最后五轴自审台账记录file:line证据、预测反对意见与缓解措施机器校验通过才提交。AI 产出必须过门禁才能发布安全扫描 → 二审 → AIGC 显式标识。改写和润色会整篇覆盖正文所以每次覆盖后必须补回 AIGC 文末声明幂等打标。写作风格不是每次临时描述而是落成程序内的风格档案文件每次写稿/改写/润色都注入改文件即改全平台产出风格。这套纪律的核心是AI 生成的内容不直接进生产环境。默认走草稿人审只有配置开关打开后才允许直发。出问题的概率低到可以接受但一旦出问题last_error和门禁日志能定位到是哪道闸拦的。取舍什么时候不该用这套平台数量 3手动发比维护自动化便宜。内容更新频率 1 篇/周登录态复用和队列系统的复杂度收益不大。平台 API 开放且稳定直接调 API 比浏览器自动化可靠得多。浏览器方案是最后的手段。需要高并发SQLite 队列 单 patchright 实例的吞吐上限明显几百篇并发会排队。检查清单每个适配器的key_selectors是否有 e2e 回归测试覆盖登录态 snapshot 是否在浏览器关窗前主动写出MetaWeblog 平台是否使用访问令牌而非密码Edge profile 是否清理或新建避免跟踪防护累积headless 模式下是否用真实鼠标坐标而非合成点击登录状态判断是否走 cookie jar HTTP 探测而非 URL选择器类名变更前是否跑过 e2e小屏视口下顶栏是否有 overflow 兜底和 nowrap发布前是否跑过--dry-run验证门禁全链路配置中ALLOW_AI_DIRECT_PUBLISH是否保持false直到人工确认本文由 AI 辅助生成内容基于实测经验整理不构成对任何平台自动化行为的完整描述。
返回列表