用Python 爬虫,如何破解谷歌验证码?
ReCAPTCHA 介紹
可能大家還沒聽說過什么是 ReCAPTCHA,可能由于某些原因,這個驗證碼在國內出現不多,不過想必大家應該多多少少見過或用過。它長這個樣子:
這時候,只要我們點擊最前面的復選框,驗證碼算法會首先利用其「風險分析引擎」做一次安全檢測,如果直接檢驗通過的話,我們會直接得到如下的結果:
如果算法檢測到當前系統存在風險,比如可能是陌生的網絡環境,可能是模擬程序,會需要做二次校驗。它會進一步彈出類似如下的內容:
比如上面這張圖,驗證碼頁面會出現九張圖片,同時最上方出現文字「樹木」,我們需要點選下方九張圖中出現「樹木」的圖片,點選完成之后,可能還會出現幾張新的圖片,我們需要再次完成點選,最后點擊「驗證」按鈕即可完成驗證?;蛘呶覀兛梢渣c擊下方的「耳機」圖標,這時候會切換到聽寫模式,驗證碼會變成這樣:
這時候我們如果能填寫對驗證碼讀的音頻內容,同樣可以通過驗證。這兩種方式都可以通過驗證,驗證完成之后,我們才能完成表單的提交,比如完成登錄、注冊等操作。這種驗證碼叫什么名字?這個驗證碼就是 Google 的 ReCAPTCHA V2 驗證碼,它就屬于行為驗證碼的一種,這些行為包括點選復選框、選擇對應圖片、語音聽寫等內容,只有將這些行為校驗通過,此驗證碼才能通過驗證。相比于一般的圖形驗證碼來說,此種驗證碼交互體驗更好、安全性會更高、破解難度更大。
其實上文所介紹的驗證碼僅僅是 ReCAPTCHA 驗證碼的一種形式,是 V2 的顯式版本,另外其 V2 版本還有隱式版本,隱式版本在校驗的時候不會再顯式地出現驗證頁面,它是通過 JavaScript 將驗證碼和提交按鈕進行綁定,在提交表單的時候會自動完成校驗。除了 V2 版本,Google 又推出了最新的 V3 版本,reCAPTCHA V3 驗證碼會為根據用戶的行為來計算一個分數,這個分數代表了用戶可能為機器人的概率,最后通過概率來判斷校驗是否可以通過。其安全性更高、體驗更好。
體驗
那哪里可以體驗到 ReCAPTCHA 呢?我們可以打開這個網站:https://www.google.com/recaptcha/api2/demo,建議科學上網,同時用匿名窗口打開,這樣的話測試不會受到歷史 Cookies 的干擾,如圖所示:
這時候,我們可以看到下方有個 ReCAPTCHA 的窗口,然后點擊之后就出現了一個驗證圖塊。
當然靠人工是能解的,但對于爬蟲來說肯定不行啊,那怎么自動化解呢?
接下來我們就來介紹一個簡單好用的平臺。
解決方案
本次我們介紹的一個 ReCAPTCHA 破解服務叫做 YesCaptcha,主頁是http://yescaptcha.365world.com.cn/,它現在同時可以支持 V2 和 V3版本的破解。
我們這次就用它來嘗試解一下剛才的 ReCAPTCHA 上的 V2 類型驗證碼:https://www.google.com/recaptcha/api2/demo。
簡單注冊之后,可以找到首頁有一個 Token。我們可以復制下來以備后面使用,如圖所示:
它有兩個關鍵的 API,一個是創建驗證碼服務任務,另一個是查詢任務狀態,API 如下:
-
創建任務:http://api.yescaptcha.365world.com.cn/v3/recaptcha/create
-
查詢狀態:http://api.yescaptcha.365world.com.cn/v3/recaptcha/status
API 文檔可以參考這里:http://docs.yescaptcha.365world.com.cn/
經過 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/recaptcha/api2/demo
那 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?=?0while?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?+=?1time.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 的破解。需要更多資料可以關注關注號 編程簡單學丶
總結
以上是生活随笔為你收集整理的用Python 爬虫,如何破解谷歌验证码?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 从入门到精通之入门篇
- 下一篇: Python自学编程开发路线图