用 Playwright 在服务器上实现微信扫码登录:二维码提取与 Cookie 落盘
很多国内站点的登录只支持微信扫码,没有开放 OAuth 接口。如果想让服务器上的脚本自动续期,就得用无头浏览器把二维码抠出来给人扫。这套方案我在华为云上跑通了,记录一下。
一、登录入口
华为云的统一登录页是:
https://auth.huaweicloud.com/authui/login?service=<业务地址>&locale=zh-cn
页面上有账号密码、手机号、微信等多个 tab,微信按钮的 DOM id 是 #thirdLoginWx。
二、点击微信按钮的正确姿势
这个页面是 Angular 写的,按钮绑的是 ng-click。直接 element.click() 往往没反应,因为 Angular 的 scope 没被触发。用 Angular 自己的 API 更可靠:
page.evaluate("""() => {
const el = document.querySelector('#thirdLoginWx');
angular.element(el).scope().item.click();
}""")
点击后页面会跳到 open.weixin.qq.com/connect/qrconnect?...,二维码就在这个页面的 img.js_qrcode_img 里。
三、把二维码图片取出来
src 可能是相对路径,需要补全域名。直接用页面的 request 上下文去拉图片,会自动带上 Referer,避免被防盗链拦掉:
src = img.get_attribute("src")
url = src if src.startswith("http") else "https://open.weixin.qq.com" + src
resp = page.request.get(url, headers={"Referer": page.url})
data = resp.body()
拿到二进制后写文件,同样用临时文件加原子替换,权限 600。
四、等待扫码成功
微信扫码完成后,qrconnect 会带着 code 参数跳回华为云的回调地址,最终落到 developer.huaweicloud.com。所以判断条件很简单:
if page.url.startswith("https://developer.huaweicloud.com/"):
# 登录成功
这时用 ctx.cookies() 导出全部 Cookie,过滤出 huaweicloud.com 域下的,转成脚本能用的 JSON 格式。
五、二维码会过期
微信二维码有效期大约 5 分钟。我的处理是每 25 秒重新抓一次图片(页面上的二维码会自己刷新),并且超过 4 分钟就 page.reload() 重新走一遍流程。
六、进程不要被 systemd 带走
这个登录脚本是由 Web 面板用 subprocess.Popen 拉起的。如果面板本身是 systemd 服务,重启面板时 cgroup 会把子进程一起杀掉。必须加:
subprocess.Popen(args, start_new_session=True)
start_new_session=True 让子进程脱离当前会话,面板重启也不影响正在等待扫码的浏览器。
七、无头模式的启动参数
服务器上一般没有桌面环境,Chrome 需要这些参数才能起来:
args=["--no-sandbox", "--disable-dev-shm-usage", "--disable-gpu"]
--disable-dev-shm-usage 尤其重要,容器里 /dev/shm 默认只有 64MB,不加这个参数页面会随机崩溃。
整套流程跑下来,从点击按钮到拿到可用 Cookie 大约 5 秒,剩下就是等人扫码。
- 点赞
- 收藏
- 关注作者
评论(0)