当前位置: 首页 > 后端技术 > Node.js

NodejsPlaywright2Captcha验证码识别实现自动登录_0

时间:2023-04-03 23:32:51 Node.js

原文:https://lwebapp.com/zh/post/b...在日常工作中,为了提高工作效率,我们可能会编写脚本来自动执行任务.有些网站需要用户登录,所以脚本的自动登录功能必不可少。但是,我们在登录网站的时候,经常会出现验证码。验证码的目的是防止机器登录和自动化脚本操作。那么有没有办法让脚本自动识别验证码登录呢?下面我就以B站为例,给大家讲解一下如何解决自动登录脚本中最关键的验证码问题。探索,首先需要体验本网站的登录方式,了解其验证码类型。打开B站https://www.bilibili.com/,打开控制台,点击登录,中间会弹出一个登录小框。通常,输入帐号和密码后,会弹出一个验证码框。我们猜验证码这个时候已经请求接口了。由于验证码的英文是captcha,我们在网络面板中搜索captcha,找到了一个与验证码相关的界面https://passport.bilibili.com/x/passport-login/captcha点击查看界面和返回结果,确实有一些有用的信息,我们发现验证码类型是geetest。{“代码”:0,“消息”:“0”,“ttl”:1,“数据”:{“类型”:“geetest”,“token”:“b416c387953540608bb5da384b4e372b”,“geetest”:{“挑战”:"aeb4653fb336f5dcd63baecb0d51a1f3","gt":"ac597a4506fee079629df5d8b66dd4fe"},"tencent":{"appid":""}}}搜索后发现B站使用的验证码服务是geetest提供的,国内很多网站使用此服务,geetest验证码的特点是移动拼图,按顺序选择单词或数字。那么,我们想办法识别geetest验证码。小编了解了市面上的验证码方案。结果比较好的基本都是OCR服务商。经过对比,发现2Captcha的服务很好,解码速度快,服务器连接稳定,支持多语言API,价格合理。小编决定试试2Captcha。接下来2Captcha官网展示了使用Nodejs+Playwright+2Captcha解决B站登录验证码问题,如果想使用其他语言和框架,比如Python+Selenium,也可以参考这个tutorial,和解决问题的思路是一样的。解决如何识别验证码,先仔细阅读官方文档2CaptchaAPIGeetest。解决方法写的很详细。简单来说就是通过拦截网站接口,获取gt和challenge两个验证码参数,请求http://2captcha.com/in.php,获取验证码ID再请求http://2captcha.com/res.php一段时间后,得到challenge、validate、seccode的标识,如何应用验证结果得到最关键的validate后,模拟用户填写账号密码登录,拦截返回参数验证码请求接口的,替换为验证成功的参数,然后触发登录接口。下面我们来分析一下详细步骤和环境准备。我们先搭建一个脚本执行环境。我们使用Node.js+Playwright编写脚本。首先确保电脑本地已经安装了Nodejs,然后新建一个空项目,安装Playwrightmkdirbypass-captchacdbypass-captchanpminitnpmi-Dplaywright我们使用Playwright的库模式,详细文档:Playwright新建脚本文件captcha.js在项目根目录,填写如下内容,在命令行运行nodecaptcha.js简单测试一下项目能否正常启动const{chromium}=require("playwright");(async()=>{constbrowser=awaitchromium.launch({headless:false,});constpage=awaitbrowser.newPage();awaitpage.goto("https://www.bilibili.com/");awaitbrowser.close();})();正常情况会弹出谷歌浏览器界面,显示B站首页,然后浏览器会自动关闭。请求in.php接口。先梳理一下请求http://2captcha.com/in.php接口需要的参数。你可以看到参数列表。我们注意所需的参数。参数类型是必需的。说明keyString是你的APIkeymethodString是geetest-定义你发送的是Geetest的验证码gtString是gt参数challengeString是在目标网站上找到的挑战字符串参数api_serverString不是api_server参数pageurlString是你在目标上看到的website验证码所在页面的完整URLheader_acaoInteger默认值:0否0-禁用1-启用。如果启用in.php将在响应中包含Access-Control-Allow-Origin:*标头。用于Web应用程序中的跨域AJAX请求。res.php还支持pingbackString解析验证码时将发送的pingback(回调)响应的无URL。URL应该在服务器上注册。更多信息在这里jsonInteger默认值:0否0-服务器将以纯文本形式发送响应1-告诉服务器以JSON格式发送响应soft_idInteger否软件开发人员的ID。将其软件与2Captcha集成的开发人员将获得奖励:软件用户支出的10%。proxyString否格式:login:password@123.123.123.123:3128您可以在此处找到有关代理的更多信息。proxytypeString否代理类型:HTTP、HTTPS、SOCKS4、SOCKS5.userAgentString否您的userAgent将传递给我们的工作人员并用于解决验证码。关键是在2Captcha官网注册一个账号,在后台面板的账号设置里面会有一个APIkey。当然,要让钥匙生效,还需要充值一定的钱。该方法是一个固定值。见于。但是这里有一点要注意,gt是每个网站只有一个值,B站这里是一个固定的ac597a4506fee079629df5d8b66dd4fe,但是challenge是一个动态值,每次API请求都会得到一个新的challenge值。验证码加载到页面后,挑战值将失效。因此需要在网站登录页面加载时监听https://passport.bilibili.com/x/passport-login/captcha请求,每次重新识别一个新的挑战值。下面将解释如何监控它。pageurl就是登录页的地址https://www.bilibili.com/于是我们可以得到类似这样一个请求接口http://2captcha.com/in.php?key=1abc234de56fab7c89012d34e56fa7b8&method=geetest>=ac597a4506fee079629df5d8b66dd4fe&challenge=12345678abc90123d45678ef90123a456b&pageurl=https://www.bilibili.com/接下来就是解决每次进入首页获取新挑战值的问题。模拟用户的点击登录过程。首先,启动谷歌浏览器,打开B站首页,点击最上方的登录按钮,会弹出一个登录框。这个时候验证码接口已经下发了。这里监听验证码接口返回的参数,可以拦截gt和challenge的值。const{chromium}=require("playwright");(async()=>{//选择Chrome浏览器,设置headless:false可以看到浏览器界面constbrowser=awaitchromium.launch({headless:false,});constpage=awaitbrowser.newPage();//打开B站awaitpage.goto("https://www.bilibili.com/");const[response]=awaitPromise.all([//请求验证码interfacepage.waitForResponse((response)=>response.url().includes("/x/passport-login/captcha")&&response.status()===200),//点击顶部的登录按钮page.click(".header-login-entry"),]);//获取接口返回信息constresponseJson=awaitresponse.body();//解析出gt并挑战constjson=JSON.parse(responseJson);constgt=json.data.geetest.gt;constchallenge=json.data.geetest.challenge;console.log("获取gt",gt,"挑战",挑战);//暂停5秒,防止浏览器关闭太快,来不及看到效果sleep(5000);//关闭浏览器awaitbrowser.close();})();/***模拟休眠功能,延时一定时间,单位毫秒*延时毫秒数*/functionsleep(delay){varstart=newDate().getTime();while(newDate().getTime()