原文:https://lwebapp.com/zh/post/bypass-captcha
需求
日常工作当中,为了提高工作效率,我们可能会写脚本来自动执行任务。有些网站因为需要用户登陆,所以脚本的自动登陆功能必不可少。
不过我们在登陆网站的时候经常会出现验证码,验证码的目的就是为了防止机器登陆、自动化脚本操作,那么有没有办法让脚本能自动识别验证码实现登陆呢?
接下来我以 B 站为例给大家讲解下,如何解决自动登陆脚本中最关键的验证码问题。
探索
首先需要体验下这个网站的登陆方式,了解下它的验证码类型。
打开 B 站 https://www.bilibili.com/ ,打开控制台,点击登陆,这时候会弹出中间小的登陆框,通常输入完账号和密码,就会弹出验证码框了,我们猜测验证码的接口此时已经请求了。
由于验证码的英文是 captcha
,我们在 network
面板里搜 captcha
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cv3sLJ37-1649653499343)(https://cdn.jsdelivr.net/gh/openHacking/static-files@main/uPic/uTools_1649263456820.png)]
发现了一个和验证码相关的接口
https://passport.bilibili.com/x/passport-login/captcha
点开看接口返回结果,果然有一些有用的信息,我们发现验证码类型是 geetest
。
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"type": "geetest",
"token": "b416c387953540608bb5da384b4e372b",
"geetest": {
"challenge": "aeb4653fb336f5dcd63baecb0d51a1f3",
"gt": "ac597a4506fee079629df5d8b66dd4fe"
},
"tencent": {
"appid": ""
}
}
}
通过搜索发现了 B 站使用的验证码服务是 geetest
提供的,国内有很多网站都用的这个服务, geetest
验证码的特点是移动拼图、按顺序选择文字或者数字。
那么接下来,就来寻找可以识别 geetest
验证码的办法。
小编了解了市面上提供的验证码解决方案,效果比较好的基本都是 OCR 服务商,对比之后发现 2Captcha 的服务非常好,解码速度快、服务器连接稳定、支持多种语言 API、价格公道,小编决定试用下 2Captcha
。
接下来就展示使用 Nodejs
+ Playwright
+ 2Captcha
来解决 B 站的登陆验证码问题。
如果想用其他语言和框架,比如
Python
+Selenium
,也可以参照这个教程,解决问题的思路都是一样的。
解决
- 如何识别验证码
先仔细阅读官方文档 2Captcha API Geetest,解决方案写的很详细,简单来说
- 通过拦截网站接口,获取
gt
、challenge
这两个校验码参数,请求http://2captcha.com/in.php
,得到验证码ID
- 隔一段时间再请求
http://2captcha.com/res.php
,得到校验成功的标识challenge
、validate
、seccode
- 如何应用验证结果
拿到最关键的 validate
之后,模拟用户填写账号密码登陆,拦截验证码请求接口的返回参数,替换为校验成功的参数,随即触发登陆接口。
接下来,我们分析下详细步骤
环境准备
我们先搭建一下脚本执行环境。
我们使用 Node.js
+ Playwright
来写脚本。
-
先确保你的电脑本地已经安装了 Nodejs
-
再新建空项目,安装
Playwright
mkdir bypass-captcha
cd bypass-captcha
npm init
npm i -D playwright
我们采用
Playwright
的库模式,详细文档:Playwright
- 在项目根目录新建一个脚本文件
captcha.js
,填入以下内容,命令行运行node captcha.js
来简单测试下是否能正常启动项目
const {
chromium
} = require("playwright");
(async () => {
const browser = await chromium<