谷歌reCaptcha协议提交解决思路介绍

本篇介绍供思路参考,文内介绍的参考DEMO:requestsselenium

本教程是几年前基于旧版api接口编写的,目前api接口是新版本,原理一样 只是格式不同请勿钻牛角尖

ReCAPTCHA 介绍

可能大家还没听说过什么是 ReCAPTCHA,可能由于某些原因,这个在国内出现不多,不过想必大家应该多多少少见过或用过。它长这个样子:

 

这时候,只要我们点击最前面的复选框,算法会首先利用其「风险分析引擎」做一次安全检测,如果直接检验通过的话,我们会直接得到如下的结果:

 

如果算法检测到当前系统存在风险,比如可能是陌生的网络环境,可能是模拟程序,会需要做二次校验。它会进一步弹出类似如下的内容:

 

比如上面这张图,页面会出现九张图片,同时最上方出现文字「树木」,我们需要点选下方九张图中出现「树木」的图片,点选完成之后,可能还会出现几张新的图片,我们需要再次完成点选,最后点击「验证」按钮即可完成验证。 或者我们可以点击下方的「耳机」图标,这时候会切换到听写模式,会变成这样:

 

这时候我们如果能填写对读的音频内容,同样可以通过验证。 这两种方式都可以通过验证,验证完成之后,我们才能完成表单的提交,比如完成登录、注册等操作。 这种叫什么名字? 这个就是 Google 的 ReCAPTCHA V2 ,它就属于行为验证的一种,这些行为包括点选复选框、选择对应图片、语音听写等内容,只有将这些行为校验通过,此验证码才能通过验证。相比于一般的图形验证码来说,此种验证码交互体验更好、安全性会更高、破解难度更大。

其实上文所介绍的仅仅是 ReCAPTCHA 的一种形式,是 V2 的显式版本,另外其 V2 版本还有隐式版本,隐式版本在校验的时候不会再显式地出现验证页面,它是通过 JavaScript 将和提交按钮进行绑定,在提交表单的时候会自动完成校验。除了 V2 版本,Google 又推出了最新的 V3 版本,reCAPTCHA V3 会为根据用户的行为来计算一个分数,这个分数代表了用户可能为机器人的概率,最后通过概率来判断校验是否可以通过。其安全性更高、体验更好。

体验

那哪里可以体验到 ReCAPTCHA 呢?我们可以打开这个网站:https://www.google.com/recaptcha/api2/demo,建议科学上网,同时用匿名窗口打开,这样的话测试不会受到历史 Cookies 的干扰,如图所示:

 

这时候,我们可以看到下方有个 ReCAPTCHA 的窗口,然后点击之后就出现了一个验证图块。

当然靠人工是能解的,但对于爬虫来说肯定不行啊,那怎么自动化解呢?

接下来我们就来介绍一个简单好用的平台。

解决方案

本次我们介绍的一个 ReCAPTCHA 破解服务叫做 YesCaptcha,主页是 https://yescaptcha.com/,它现在同时可以支持 V2 和 V3版本的破解。

我们这次就用它来尝试解一下刚才的 ReCAPTCHA 上的 V2 类型:https://www.google.com/recaptcha/api2/demo。

简单注册之后,可以找到首页有一个 Token。我们可以复制下来以备后面使用,如图所示:

 

它有两个关键的 API,一个是创建服务任务,另一个是查询任务状态,API 如下:

API 文档可以参考这里:https://yescaptcha.atlassian.net/wiki/spaces/YESCAPTCHA/pages/229796

经过 API 文档可以看到使用的时候可以配置如下参数:

参数名

是否必须

说明

参数名

是否必须

说明

token

请在个人中心获取 (Token)

websiteKey

ReCaptcha SiteKey (固定参数)

websiteURL

ReCaptcha Referer (一般也为固定参数)

type

NoCaptchaTaskProxyless、RecaptchaV2TaskProxyless

这里就有三个关键信息了:

  • token:就是刚才我们在 YesCaptcha 上复制下来的参数

  • websiteKey:这个是 ReCAPACHA 的标志字符串,稍后我们会演示怎么找。

  • websiteURL,一般是 ReCAPTCHA 的来源网站的 Referer,比如对于当前的案例,该值就是

那 siteKey 怎么找呢?其实很简单,我们看下当前 ReCAPTCHA 的 HTML 源码,从源码里面找一下就好了:

 

这里可以看到每个 ReCAPTCHA 都对应一个 div,div 有个属性叫做 date-sitekey,看这里的值就是:

6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-

好,万事俱备了,只差代码了!

开工

本教程是几年前基于旧版api接口编写的,目前api接口是新版本,原理一样 只是格式不同请勿钻牛角尖

我们就用最简单 requests 来实现下吧,首先把常量定义一下:

TOKEN = '50a07xxxxxxxxxxxxxxxxxxxxxxxxxf78'  # 请替换成自己的TOKEN TYPE = "NoCaptchaTaskProxyless" # 验证码类型,reCaptchaV2 是 NoCaptchaTaskProxyless REFERER = 'https://www.google.com/recaptcha/api2/demo' BASE_URL = 'http://api.yescaptcha.com' # 以前的旧版服务器地址:http://api.yescaptcha.365world.com.cn 已停用 SITE_KEY = '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-' # 请替换成自己的SITE_KEY

这里我们定义了这么几个常量:

  • TOKEN:就是网站上复制来的 token

  • REFERER:就是 Demo 网站的链接

  • API_BASE_URL:就是 YesCaptcha 的 API 网址

  • SITE_KEY:就是刚才我们找到的 data-sitekey

然后我们定义一个创建任务的方法:

def create_task(): url = F"{BASE_URL}/createTask" data = { "clientKey": TOKEN, "task": { "websiteURL": REFERER, "websiteKey": SITE_KEY, "type": TYPE } } try: response = requests.post(url, json=data, verify=False) if response.status_code == 200: data = response.json() print('response data:', data) return data.get('taskId') except requests.RequestException as e: print('create task failed', e)

这里就是调 API 来创建任务,没什么好说的。

如果创建成功之后会得到一个 task_id,接下来我们就需要用这个 task_id 来轮询查看任务的状态,定义如下的这么一个方法:

这里就是设置了最长轮询次数 120 次,请求的 API 就是查询任务状态的 API,会得到一个任务状态的结果,如果结果是 Success,那就证明任务成功了,解析其中的 response 结果就是之后得到的 token。

两个方法调用一下:

运行结果类似如下:

如果其返回的是如上格式的数据,就代表 ReCAPTCHA 已经识别成功了,其返回的 response 字段的内容就是识别的 token,我们直接拿着这个 token 放到表单里面提交就成功了。

那这个 token 怎么来用呢? 其实如果我们用浏览器验证验证成功之后,点击表单提交的时候,在其表单里面会把一个 name 叫做 g-recaptcha-response 的 textarea 赋值,如果验证成功,它的 value 值就是验证之后得到的 token,这个会作为表单提交的一部分发送到服务器进行验证。如果这个字段校验成功了,那就没问题了。

 

所以,如上的过程相当于为我们模拟了点选的过程,其最终得到的这个 token 其实就是我们应该赋值给 name 为 g-recaptcha-response 的内容。 那么怎么赋值呢? 很简单,用 JavaScript 就好了。我们可以用 JavaScript 选取到这个 textarea,然后直接赋值即可,代码如下:

注意这里的 TOKEN_FROM_YESCAPTCHA 需要换成刚才我们所得到的 token 值。我们做爬虫模拟登录的时候,假如是用 Selenium、Puppeteer 等软件,在模拟程序里面,只需要模拟执行这段 JavaScript 代码,就可以成功赋值了。 执行之后,直接提交表单,我们查看下 Network 请求:

 

可以看到其就是提交了一个表单,其中有一个字段就是 g-recaptcha-response,它会发送到服务端进行校验,校验通过,那就成功了。 所以,如果我们借助于 YesCaptcha 得到了这个 token,然后把它赋值到表单的 textarea 里面,表单就会提交,如果 token 有效,就能成功绕过登录,而不需要我们再去点选了。 最后我们得到如下成功的页面:

当然我们也可以使用 requests 来模拟完成表单提交:

最后完善一下调用:

运行结果如下:

最后就可以发现,模拟提交之后,结果会有一个 Verification Success... Hooray! 的文字,就代表验证成功了!

至此,我们就成功完成了 ReCAPTCHA 的破解。

上面我们介绍的是 requests 的实现,当然使用 Selenium 等工具也可以实现,具体的 Demo 在文档也写好了,请大家参考文档的说明使用即可。