使用 Playwright + GitHub Actions 完成一些页面自动化任务的初步探索(下)

发布时间:2026/7/21 6:32:59
使用 Playwright + GitHub Actions 完成一些页面自动化任务的初步探索(下) 书接上回我们继续自动化反抄袭和反剽窃的行动详情参见我的上一篇文章《51CTO一个抄袭剽窃的流氓网站》。在上一篇文章中我们搭建了 MVP 项目也以测试通过。现在要着手解决登录问题了。1. 通过认证的方案汇总我们所有操作的前提是要获取被访问网站的身份。梳理各种解决方案可以分为这样几种第一种完全自动化模拟登录但因为大多数网站在登录过程中会设置图片验证环节使得这种方式基本不太可行。有一些方案会调用第三方的 OCR API 试图攻克这一难题理论上对于部分类型的验证应该是有效的但本文不会深究。第二种手动登录将数据保留下来供下次复用。Playwright 提供的context.storageState()方法就是为此设计的awaitcontext.storageState({path:state.json});第三种直接使用本地真实浏览器数据。Playwright 提供的constcontextawaitchromium.launchPersistentContext(C:\\Users\\你的用户名\\AppData\\Local\\Google\\Chrome\\User Data,{channel:chrome,headless:false});第四种从浏览器中导出 cookie然后在 Playwright 中复用以上几种方法第一种方法因验证码问题被排除第二种方法在测试时发现会卡在验证码环节验证码总是失败第三种和第四种方法均可行最后选择的是第四种方法。2. 导出 Cookie既然我们选择了复用 cookie 的方案那么第一步就是要把 cookie 准备好。这部分工作有些繁琐并不容易实现可以借助 AI 来辅助处理。首先使用浏览器的 Cookie 插件将目标站点的 cookie 导出为 json 文件。我使用的工具是 Cookie Manager。但是要注意的是使用工具导出的 Cookie 一般都不会被 Playwright 直接接受因为里面有一些字段不是 Playwright 认可的并且还有很多项是与身份信息无关的建议把导出的 json 交给 AI说明诉求请 AI 处理一下就可以得到精简且有效的 cookie 信息了。这里就不方便展示详细的 cookie 信息了。3. 复用 Cookie 验证是否登录成功我们把处理好的 cookie 保存为cookie.json放到工程根目录下然后修改我们在上一篇文章中的main.ts文件使用await context.addCookies(cookies)把我们预先存储好的 cookie 文件加载上然后访问一个只有在登录后才能访问的页面import{chromium}fromplaywright;import{readFile}fromfs/promises;asyncfunctionmain(){constbrowserawaitchromium.launch({headless:true});constcontextawaitbrowser.newContext();constcookiesJSON.parse(awaitreadFile(cookie.json,utf8));awaitcontext.addCookies(cookies);constpageawaitcontext.newPage();// 打开登录页awaitpage.goto(https://a/page/that/only/show/up/after/login);// await page.waitForLoadState(networkidle);// 等待目标内容加载完毕awaitpage.waitForSelector(.span_read);console.log(awaitpage.content());awaitbrowser.close();}main().catch(err{console.error(err);process.exit(1);});注意这里可能会遇到一个问题那就是很多系统的页面并不是在请求 url 时就会加载的而是在页面 load 完毕后调用 js 发送 AJAX 请求后再渲染出来的所以如果只是单纯的使用page.goto(...)打开页面后就直接操纵页面的话大概率是会失败的如果把页面内容打印出来就会发现HTML 内容与真实浏览器显示的相差很多。这时候我们通常需要给页面加载留出一些等待时间例如使用await page.waitForLoadState(networkidle)但这个方法并不保险很多时候在等待它延时结束后目标内容可能还未渲染出来所以最保险的做法就是等待你需要操作的内容就绪就如同上述代码所做的那样await page.waitForSelector(.span_read)。4. 选定操作目标模拟点击操作当页面全部加载完毕后就可以使用 Playwright 的 API 模拟用户操作了这是 Playwright 功能最强大的地方它对于页面的模拟操作简单而有效。首先是要选定页面上的目标在这一点和几乎所有的页面自动化测试框架或爬虫工具一样Playwright 也支持 CSS selector这使得我们在选择操作目标时也变得极其容易以下代码就展示了如何选择页面上所有classspan_read的元素constbtnspage.locator(.span_read);而以下代码则是选择第一个元素然后模拟在它上面执行单击操作awaitbtns.nth(0).click();5. 等待并确认点击是否已成功执行大多数情况下在模拟点击之后我们都需要等待并确认点击是否已成功执行这么做有很现实的原因脚本必须确保操作执行成功后才能进行下一步操作否则页面会报错下一步操作要在上一步执行成功后渲染出的 HTML 元素基础上执行这里我们列举两种判断上一个操作执行成功的方法。5.1 根据 DOM 出现标志性元素判定执行成功假设我们点击了一个按钮当它执行成功后某个 DOM 元素里会填入 “完成” 字样就像这样完成这是后台执行完毕后在前台的反馈信息它可以作为这个点击操作执行完毕的完美“标志”如果我们要等待并确认点击是执行完毕可以这样写awaitbtn.click();awaitexpect(page.locator(.done)).toHaveText(完成);5.2 根据 DOM 标志性元素消失判定执行成功在另外一些场景里当我们点击了一个按钮在它执行成功后某个 DOM 元素可能会被移除这也是后台执行完毕后在前台的反馈信息可以作为这个点击操作执行完毕的完美“标志”。如果我们要等待并确认点击操作执行完毕可以这样写awaitbtn.click();// 完成后会消失的元素constflagpage.locator(.done);awaitflag.waitFor({state:detached,timeout:30000});6. GitHub Actions 工作流的注意事项GitHub Actions 的工作流使用 yaml 文件描述必须放置于工程根目录下的.github\workflows\文件夹下。代码提交后GitHub 能自动识别出目录里的工作流描述文件并能在 GitHub 项目页面的 Actions 标签中看到。不过对于免费账号来说GitHub Actions 工作流的延迟是很大的很少能精准按照预定执行。晚几分钟甚至几十分钟都是常有的在测试时需要等待足够长的时间。7. 小结这次的尝试比较简单但 MVP 证明是可行的。不过个人在开发脚本中有一个比较强烈的感受那就是Playwright 脚本的复用性一般都极差因为它都是针对某一个特定页面编写的。所以我们也不打算给大家分享具体的脚本实现了如果没有目标页面的结构做参照解读脚本的操作无异于讲天书。