来写一下令爬虫工程师闻风丧胆的极验验证码
的绕过方案,对接的是一个俄罗斯的打码平台 2captcha
先来看案例,网址:https://account.quandashi.com/
在登录账号的时候,会弹出极验的点选验证码
应对这种相对专业、更新频率较高的验证码,还是直接对接打码平台比较高效,首先就是在2captcha注册一个账号,充值,然后对接文档2captcha的接口文档
通过查阅文档,我们得知,极验的验证过程,无非就是获取 challenge
gt
api_server
,发送到接口后返回 validate
seccode
,然后拿到这两个参数去验证的过程
接下来,我们通过抓包分析各个参数的获取过程
challenge 和 gt
从抓包得知,这两个参数可以从 /gee-test-code
接口获取,实现代码:
1 2 3 4
| def get_gt_challenge(): api = f"https://account.quandashi.com/passport/gee-test-code?t={round(time.time() * 10 ** 3)}" res = session.get(api).json() return res["challenge"], res["gt"]
|
validate 和 seccode
带上challenge两个参数,发送到 2captcha的 /in.php
接口
1 2 3 4 5 6 7 8 9 10 11
| def send_to_captcha(gt, challenge): in_api = "http://2captcha.com/in.php" form_data = { "key": key_2captcha, "method": "geetest", "gt": gt, "challenge": challenge, "pageurl": page_url, } res = session.get(in_api, params=form_data) return res.text.strip("OK|")
|
- pageurl 是可选的,就是从哪个页面进行验证
- key 即是自己的 2captcha凭证
请求接口后会返回一个 captcha_id
,后续要根据这个id去请求 /res.php
接口,获取验证结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| def get_validate_seccode(captcha_id): """ Make a 15-20 seconds timeout """ res_api = "http://2captcha.com/res.php" params = { "key": key_2captcha, "id": captcha_id, "action": "get", } res = session.get(res_api, params=params) if res.text.startswith("OK"): vali_result = json.loads(res.text.strip("OK|")) print(vali_result) return vali_result["geetest_validate"], vali_result["geetest_seccode"] elif res.text == "CAPCHA_NOT_READY": return "not ready" elif res.text == "ERROR_CAPTCHA_UNSOLVABLE": return "unsolvable"
|
处理的结果可能有以下几种情况:
OK
处理成功,拿到 validate
和 seccode
,就可以进行登录请求了
CAPCHA_NOT_READY
,验证码还没处理好,需要等一段时间再次请求
ERROR_CAPTCHA_UNSOLVABLE
无法处理验证码,需要重新获取 challenge 拿去处理
拿到 validate
和 seccode
就可以去请求登录接口了
1 2 3 4 5 6 7 8 9 10 11 12
| def login(): api = "https://account.quandashi.com/passport/dologin"
challenge, seccode, validate = gen_session_id() form_data = { "adminAccount": "", "adminPwd": "", "geetest_challenge": challenge, "geetest_validate": validate, "geetest_seccode": seccode, } res = session.post(api, data=form_data)
|
登录成功: