乐趣区

关于python:Python-爬虫如何破解谷歌验证码

之前介绍过 Google ReCAPTCHA 验证码的绕过办法,过后介绍的是用 2Captcha,然而有些敌人跟我反映说 2Captcha 价格比拟贵,而且用起来比较复杂。

明天再给大家介绍另一个用于破解 Google ReCAPTCHA 的办法。

ReCAPTCHA 介绍

可能大家还没听说过什么是 ReCAPTCHA,可能因为某些起因,这个验证码在国内呈现不多,不过想必大家应该多多少少见过或用过。它长这个样子:

这时候,只有咱们点击最后面的复选框,验证码算法会首先利用其「危险剖析引擎」做一次平安检测,如果间接测验通过的话,咱们会间接失去如下的后果:

如果算法检测到以后零碎存在危险,比方可能是生疏的网络环境,可能是模拟程序,会须要做二次校验。它会进一步弹出相似如下的内容:

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

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

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

体验

那哪里能够体验到 ReCAPTCHA 呢?咱们能够关上这个网站:https://www.google.com/recapt…,倡议迷信上网,同时用匿名窗口关上,这样的话测试不会受到历史 Cookies 的烦扰,如图所示:

这时候,咱们能够看到下方有个 ReCAPTCHA 的窗口,而后点击之后就呈现了一个验证图块。

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

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

解决方案

本次咱们介绍的一个 ReCAPTCHA 破解服务叫做 YesCaptcha,主页是 http://yescaptcha.365world.co…,它当初同时能够反对 V2 和 V3 版本的破解。

咱们这次就用它来尝试解一下方才的 ReCAPTCHA 上的 V2 类型验证码:https://www.google.com/recapt…。

简略注册之后,能够找到首页有一个 Token。咱们能够复制下来以备前面应用,如图所示:

它有两个要害的 API,一个是创立验证码服务工作,另一个是查问工作状态,API 如下:

  • 创立工作:http://api.yescaptcha.365worl…
  • 查问状态:http://api.yescaptcha.365worl…

API 文档能够参考这里:http://docs.yescaptcha.365wor…

通过 API 文档能够看到应用的时候能够配置如下参数:

参数名 是否必须 阐明
token 请在集体核心获取 (Token)
siteKey ReCaptcha SiteKey(固定参数)
siteReferer ReCaptcha Referer(个别也为固定参数)
captchaType ReCaptchaV2(默认) / ReCaptchaV3
siteAction ReCaptchaV3 选填 Action 动作 默认 verify
minScore ReCaptchaV3 选填 最小分数(0.1-0.9)

这里就有三个要害信息了:

  • token:就是方才咱们在 YesCaptcha 上复制下来的参数
  • siteKey:这个是 ReCAPACHA 的标记字符串,稍后咱们会演示怎么找。
  • siteReferer,个别是 ReCAPTCHA 的起源网站的 Referer,比方对于以后的案例,该值就是 https://www.google.com/recapt…

那 siteKey 怎么找呢?其实很简略,咱们看下以后 ReCAPTCHA 的 HTML 源码,从源码外面找一下就好了:

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

6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-

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

动工

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

TOKEN = '50a07xxxxxxxxxxxxxxxxxxxxxxxxxf78'  # 请替换成本人的 TOKEN
REFERER = 'https://www.google.com/recaptcha/api2/demo'
BASE_URL = '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}/v3/recaptcha/create?token={TOKEN}&siteKey={SITE_KEY}&siteReferer={REFERER}"
    try:
        response = requests.get(url)
        if response.status_code == 200:
            data = response.json()
            print('response data:', data)
            return data.get('data', {}).get('taskId')
    except requests.RequestException as e:
        print('create task failed', e)

这里就是调 API 来创立工作,没什么好说的。

如果创立胜利之后会失去一个 task_id,接下来咱们就须要用这个 task_id 来轮询查看工作的状态,定义如下的这么一个办法:

def polling_task(task_id):
    url = f"{BASE_URL}/v3/recaptcha/status?token={TOKEN}&taskId={task_id}"
    count = 0
    while count < 120:
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                print('polling result', data)
                status = data.get('data', {}).get('status')
                print('status of task', status)
                if status == 'Success':
                    return data.get('data', {}).get('response')
        except requests.RequestException as e:
            print('polling task failed', e)
        finally:
            count += 1
            time.sleep(1)

这里就是设置了最长轮询次数 120 次,申请的 API 就是查问工作状态的 API,会失去一个工作状态的后果,如果后果是 Success,那就证实工作胜利了,解析其中的 response 后果就是验证码破解之后失去的 token。

两个办法调用一下:

if __name__ == '__main__':
    task_id = create_task()
    print('create task successfully', task_id)
    response = polling_task(task_id)
    print('get response:', response[0:40]+'...')

运行后果相似如下:

response data: {'status': 0, 'msg': 'ok', 'data': {'taskId': '1479436991'}}
create task successfully 1479436991
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Success', 'response': '03AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIed5foLb15oWvWVksq9KesDkDd7dgMMr-UmqULZduXTWr87scJXl3djhl2btPO721eFAYsVzSk7ftr4uHBdJWonnEemr9dNaFB9qx5pnxr3P24AC7cCfKlOH_XARaN4pvbPNxx_UY5G5fzKUPFDOV14nNkCWl61jwwC0fuwetH1q99r4hBQxyI6XICD3PiHyHJMZ_-wolcO1R9C90iGQyjzrSMiNqErezO24ODCiKRyX2cVaMwM9plbxDSuyKUVaDHqccz8UrTNNdJ4m2WxKrD9wZDWaSK10Ti1LgsqOWKjKwqBbuyRS_BkSjG6OJdHqJN4bpk_jAcPMO13wXrnHBaXdK4FNDR9-dUvupHEnr7QZEuNoRxwl8FnO2Fgwzp2sJbGeQkMbSVYWdAalE6fzJ8NwsFJxCdDyeyO817buBtvTJ4C06C1uZ92fpPTeYGJwbbicOuqbGfHNTyiSJeRNmt-5RKz0OUiPJOPnmVKGlWBOqwbwCW1WZt-E-hH4FEg4En5TITmmPb_feS9dWKUxudn1U0hHk2vV9PerjZLtI7F67KtgmcqRrARPbwnc6KyAi3Hy1hthP92lv4MRIcO2jx0Llvsja-G2nhjZB0ZoJwkb9106pmqldiwlXxky4Dcg7VPStiCYJvhQpRYol7Iq1_ltU2tyhMqsu_Xa8Z6Mr5ykRCLnmlLb8DV8isndrdwp84wo_vPARGRj7Up9ov-ycb5lDKTf1XRaHiMCa8d2WLy0Pjco9UnsRAPw0FW3MsBJah6ryHUUDho7ffhUUgV1k86ryJym6xbWch1sVC4D5owzrCFn6L-rSLc5SS1pza2zU5LK4kAZCmbXNRffiFrhUY8nP4T1xaR2KMhIaN8HhJQpR8sQh1Azc-QkDy4rwbYmxUrysYGMrAOnmDx9z7tWQXbJE4IgCVMx5wihSiE-T8nbF5y1aJ0Ru9zqg1nZ3GSqsucSnvJA8HV5t9v0QSG5cBC1x5HIceA-2uEGSjwcmYOMw8D_65Dl-d6yVk1YN2FZCgMWY5ewzB1RAFN1BMqKoITQJ64jq3lKATpkc5i7aTA2bRGQyXrbDyMRIrVXKnYMHegfMbDn0l4O81a8vxmevLspKkacVPiqLsAe-73jAxMvsOqaG7cKxMQO9CY3qbtD55YgN0W4p2jyNSVz3aEpffHRqYyWMsRI5LddLgaZQDoHHgGUhV580PSIdZJ5eKd0gOjxIYxKlr0IgbMWRmsG_TgDNImy1c5oey8ojl-zWpOQW7bnfq5Z4tZ10_sCTfoOZVLqRuOsqB1OOO9pLRQojLBP0HUiGhRAr_As9EIDu6F9NIQfdAmCaVvavJbi1CZITFjcywP-tBrHsxpwkCXlwl996MK_XyEDuyWnJVGiVSthUMY306tIh1Xxj93W3KQJCzsfJQcjN-3lGLLeDFddypHyG4yrpRqRHHBNyiNJHgxSk5SaShEhXvByjkepvhrKX3kJssCU04biqqmkrQ49GqBV9OsWIy0nN3OJTx8v05MP8aU8YYkYBF01UbSff4mTfLAhin6iWk84Y074mRbe2MbgFAdU58KnCrwYVxcAR8voZsFxbxNwZXdVeexNx5HlIlSgaAHLWm2kFWmGPPW-ZA7R8Wst-mc7oIKft5iJl8Ea0YFz8oXyVgQk1rd9nDR3xGe5mWL1co0MiW1yvHg'}}

如果其返回的是如上格局的数据,就代表 ReCAPTCHA 验证码曾经辨认胜利了,其返回的 response 字段的内容就是辨认的 token,咱们间接拿着这个 token 放到表单外面提交就胜利了。

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

所以,如上的过程相当于为咱们模仿了点选验证码的过程,其最终失去的这个 token 其实就是咱们应该赋值给 name 为 g-recaptcha-response 的内容。那么怎么赋值呢?很简略,用 JavaScript 就好了。咱们能够用 JavaScript 选取到这个 textarea,而后间接赋值即可,代码如下:

document.getElementById("g-recaptcha-response").innerHTML="TOKEN_FROM_YESCAPTCHA";

留神这里的 TOKEN_FROM_YESCAPTCHA 须要换成方才咱们所失去的 token 值。咱们做爬虫模仿登录的时候,如果是用 Selenium、Puppeteer 等软件,在模拟程序外面,只须要模仿执行这段 JavaScript 代码,就能够胜利赋值了。执行之后,间接提交表单,咱们查看下 Network 申请:

能够看到其就是提交了一个表单,其中有一个字段就是 g-recaptcha-response,它会发送到服务端进行校验,校验通过,那就胜利了。所以,如果咱们借助于 YesCaptcha 失去了这个 token,而后把它赋值到表单的 textarea 外面,表单就会提交,如果 token 无效,就能胜利绕过登录,而不须要咱们再去点选验证码了。最初咱们失去如下胜利的页面:

当然咱们也能够应用 requests 来模仿实现表单提交:

def verify(response):
    url = "https://www.google.com/recaptcha/api2/demo"
    data = {"g-recaptcha-response": response}
    response = requests.post(url, data=data)
    if response.status_code == 200:
        return response.text

最初欠缺一下调用:

if __name__ == '__main__':
    task_id = create_task()
    print('create task successfully', task_id)
    response = polling_task(task_id)
    print('get response:', response[0:40]+'...')
    result = verify(response)
    print(result)

运行后果如下:

response data: {'status': 0, 'msg': 'ok', 'data': {'taskId': '1479436991'}}
create task successfully 1479436991
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Working'}}
status of task Working
polling result {'status': 0, 'msg': 'ok', 'data': {'status': 'Success', 'response': '03AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIed5foLb15oWvWVksq9KesDkDd7dgMMr-UmqULZduXTWr87scJXl3djhl2btPO721eFAYsVzSk7ftr4uHBdJWonnEemr9dNaFB9qx5pnxr3P24AC7cCfKlOH_XARaN4pvbPNxx_UY5G5fzKUPFDOV14nNkCWl61jwwC0fuwetH1q99r4hBQxyI6XICD3PiHyHJMZ_-wolcO1R9C90iGQyjzrSMiNqErezO24ODCiKRyX2cVaMwM9plbxDSuyKUVaDHqccz8UrTNNdJ4m2WxKrD9wZDWaSK10Ti1LgsqOWKjKwqBbuyRS_BkSjG6OJdHqJN4bpk_jAcPMO13wXrnHBaXdK4FNDR9-dUvupHEnr7QZEuNoRxwl8FnO2Fgwzp2sJbGeQkMbSVYWdAalE6fzJ8NwsFJxCdDyeyO817buBtvTJ4C06C1uZ92fpPTeYGJwbbicOuqbGfHNTyiSJeRNmt-5RKz0OUiPJOPnmVKGlWBOqwbwCW1WZt-E-hH4FEg4En5TITmmPb_feS9dWKUxudn1U0hHk2vV9PerjZLtI7F67KtgmcqRrARPbwnc6KyAi3Hy1hthP92lv4MRIcO2jx0Llvsja-G2nhjZB0ZoJwkb9106pmqldiwlXxky4Dcg7VPStiCYJvhQpRYol7Iq1_ltU2tyhMqsu_Xa8Z6Mr5ykRCLnmlLb8DV8isndrdwp84wo_vPARGRj7Up9ov-ycb5lDKTf1XRaHiMCa8d2WLy0Pjco9UnsRAPw0FW3MsBJah6ryHUUDho7ffhUUgV1k86ryJym6xbWch1sVC4D5owzrCFn6L-rSLc5SS1pza2zU5LK4kAZCmbXNRffiFrhUY8nP4T1xaR2KMhIaN8HhJQpR8sQh1Azc-QkDy4rwbYmxUrysYGMrAOnmDx9z7tWQXbJE4IgCVMx5wihSiE-T8nbF5y1aJ0Ru9zqg1nZ3GSqsucSnvJA8HV5t9v0QSG5cBC1x5HIceA-2uEGSjwcmYOMw8D_65Dl-d6yVk1YN2FZCgMWY5ewzB1RAFN1BMqKoITQJ64jq3lKATpkc5i7aTA2bRGQyXrbDyMRIrVXKnYMHegfMbDn0l4O81a8vxmevLspKkacVPiqLsAe-73jAxMvsOqaG7cKxMQO9CY3qbtD55YgN0W4p2jyNSVz3aEpffHRqYyWMsRI5LddLgaZQDoHHgGUhV580PSIdZJ5eKd0gOjxIYxKlr0IgbMWRmsG_TgDNImy1c5oey8ojl-zWpOQW7bnfq5Z4tZ10_sCTfoOZVLqRuOsqB1OOO9pLRQojLBP0HUiGhRAr_As9EIDu6F9NIQfdAmCaVvavJbi1CZITFjcywP-tBrHsxpwkCXlwl996MK_XyEDuyWnJVGiVSthUMY306tIh1Xxj93W3KQJCzsfJQcjN-3lGLLeDFddypHyG4yrpRqRHHBNyiNJHgxSk5SaShEhXvByjkepvhrKX3kJssCU04biqqmkrQ49GqBV9OsWIy0nN3OJTx8v05MP8aU8YYkYBF01UbSff4mTfLAhin6iWk84Y074mRbe2MbgFAdU58KnCrwYVxcAR8voZsFxbxNwZXdVeexNx5HlIlSgaAHLWm2kFWmGPPW-ZA7R8Wst-mc7oIKft5iJl8Ea0YFz8oXyVgQk1rd9nDR3xGe5mWL1co0MiW1yvHg'}}
status of task Success
get response: 03AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIe...
<!DOCTYPE HTML><html dir="ltr"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, user-scalable=yes"><title>ReCAPTCHA demo</title><link rel="stylesheet" href="https://www.gstatic.com/recaptcha/releases/TbD3vPFlUWKZD-9L4ZxB0HJI/demo__ltr.css" type="text/css"></head><body><div class="recaptcha-success">Verification Success... Hooray!</div></body></html>

最初就能够发现,模仿提交之后,后果会有一个 Verification Success... Hooray! 的文字,就代表验证胜利了!

至此,咱们就胜利实现了 ReCAPTCHA 的破解。

下面咱们介绍的是 requests 的实现,当然应用 Selenium 等工具也能够实现,具体的 Demo 在文档也写好了,请大家参考文档的阐明应用即可。

以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python 编程学习圈 ,每日干货分享,发送“J”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。

退出移动版