爬蟲開發者必學:讓 Python 讀懂「滑動驗證碼」

動態網頁與靜態網頁最大的不同是資料是在什麼時間點取得的,動態網頁是在瀏覽器已經取得 HTML 後,才透過 JavaScript 在需要時動態地取得資料。因此,爬蟲程式也必須要考慮動態取得資料這件事情,才有辦法正確地找到想要的資料。「滑動驗證碼(Slider Captcha)」是驗證碼機制當中常見的典型,也是防範爬蟲程式中一種難纏的對手。這一篇文章將會利用 Python 、opencv 與 Selenium 三個工具,示範如何拆解和模擬滑動驗證碼。

常見的網頁驗證碼類型與原理

CAPTCHAs

你在瀏覽網頁的時候,有看過這些驗證機制嗎?網頁驗證碼的專業術語稱為「CAPTCHA 」(全名是 Completely Automated Public Turing test to tell Computers and Humans Apart 自動判別電腦與人類的公開圖靈測試),是目前在網頁當中常見的一種驗證機制,用來判斷惡意的使用者干擾與攻擊。目前常見的 CAPTCHA 方法有以下幾種:

  • 信件驗證碼/簡訊驗證碼
  • 圖形驗證碼
  • 問題驗證碼
  • 行為驗證碼

reCAPTCHA 計畫目前是由 Google 主要發展的驗證機制,最早是由 CMU 發起的 。reCAPTCHA 透過不同的情境讓人類回答,並藉此來幫助幫助文件數位化的進行。這個計畫將紙本掃描後無法被辨識文字顯示在問題中,讓人類在回答問題也能加以利用。

利用 Python 處理「滑動程式碼」的思路

而在「圖形驗證碼」當中,有一種常見的變形稱為「滑動驗證碼」。滑動驗證碼會動態的更新圖片與缺塊,並且要求使用者將缺塊移動到圖片中的特定位置才能通過判斷,如圖所示:

(圖片來源:資料科學家的工作日常

對於爬蟲的開發者而言,滑動驗證碼的確是一個蠻大的門檻。如何爬蟲程式可以讀得懂驗證碼,並且進一步模擬其行為都需要對網頁運作有一定的熟悉程度才行。接下來,就讓我們透過實作範例一起來體驗滑動程式碼的解決思路,我們可以分成兩個大區塊:

① 利用 Python + opencv 拆解缺塊位置

② 利用 Python + Selenium 模擬滑動行為

① 利用 Python + opencv 拆解缺塊位置

先手動把「背景圖」下載到本地端電腦,再試著利用圖像識別的方法試著找出位置。

(1)利用 cv2 將圖片讀取到程式中

OpenCV(Open Source Computer Vision Library)是用於電腦視覺的處理套件,在 Python 可以使用 opencv-python 與 cv2 進行安裝/載入。第一步,我們先利用 cv2.imread(…) 把圖片讀到程式中,並且利用 cv2.cvtColor 進行顏色轉換(原始圖片有誤差):

(圖片來源:資料科學家的工作日常

(2)判斷圖片中的物體邊緣輪廓

Canny 是圖形識別中用來作邊緣偵測(Edge Detection)的方法,細節的參數細節可以看官方文件。Canny 方法能將原始圖片轉成灰階之後,輸出包含邊緣範圍的黑白影像:

可以從結果中看到除了區塊之後,也包含很多小的零散的區塊部分:

(圖片來源:資料科學家的工作日常

(3)取出缺塊所在的位置

接下來利用 cv2.findContours() 找出圖片中所有偵測到的區塊,把他標記成藍色的部分畫出來。從長度(w)跟寬度(h)可以判斷出哪一個區塊是圖片中真正的區塊,但圖片顏色太接近的情況下會增加判斷的難度。

(圖片來源:資料科學家的工作日常

最終就可以得到缺塊所在的位置是 dx 和 dy 兩個變數:

以這個例子來說,我們就可以得知缺塊距離最左邊距離 202 px 的偏移量。

② 利用 Python + Selenium 模擬滑動行為

第二段,我們會利用 Selenium 瀏覽器測試工具幫助我們「模擬使用者移動方塊」的行為。關於 Selenium 的動態網頁模擬,之前也有寫過這一篇分享文。

(1)打開瀏覽器前往網頁,下載原始圖片

先觀察一下網頁的組成,發現給定的範例網站是利用 Canvas 動態載入圖片實現滑動驗證碼的效果的:

(圖片來源:資料科學家的工作日常

接下來利用 Selenium 打開瀏覽器跳轉到網頁中,利用 JavaScript 的先將 Canvas 轉成圖片後再進行下載 。

這麼做就可以把原始圖片下載下來,搭配「① 利用 Python + opencv 拆解缺塊位置」可以得知需要移動的偏移量。

找出按鈕元素

透過觀察網頁的結構,可以明確的找出需要被移動的方塊是位在 class = jigsaw__slider–ihcNg 的 div 元素(具體的找法,可以參考這一篇文章):

使用 Selenium 輕鬆選取:

(2)模擬使用者拖拉方塊行為

最後一步,就可以利用剛剛找出來缺塊的位置及瀏覽器模擬的工具,把方塊移動到指定的偏移位置:

實戰!讓 Python 爬蟲也能讀得懂「滑動驗證碼」

在這個例子當中,除了實作滑動驗證碼的爬蟲之外,也弄了一個簡單的滑動驗證碼作為標的。最後的成果大概像這樣,從「打開網頁」 → 「下載圖片」 → 「解析位置」 → 「模擬滑動」的整個過程:


網頁爬蟲是資料收集的一種手法,不過面對於網頁技術的變化,爬蟲程式也有不同的應對策略。

Reference

[1] 驗證碼
[2] Captcha验证码有哪些分类?有什么作用?
[3] 使用 Python + Selenium 破解滑块验证码

原文刊登於:資料科學家的工作日常讓 Python 爬蟲也能讀得懂「滑動驗證碼」