相信大家平常在瀏覽網頁的過程中,都有看過文字驗證碼(Captcha),要使用者輸入正確的英文數字才可以繼續操作,那要通過這種反爬蟲機制,就是要先把文字驗證碼(Captcha)的圖片下載下來,再進行後續的辨識動作。
這時候如果你使用圖片的src屬性來下載文字驗證碼(Captcha)圖片,會發現下載下來的圖片和網頁上的不一樣,是因為當我們發送請求到圖片的來源網址時,等於又再打開一次網頁的意思,它就會再次產生不一樣的文字驗證碼,導致下載下來的圖片會不一樣,解決方案就是使用Selenium套件來下載文字驗證碼(Captcha)圖片,這篇文章我就用博客來網站為例,來示範其中的實作方式。
- 初始化Selenium動態網頁爬蟲專案
- 使用Selenium下載文字驗證碼(Captcha)圖片
- 儲存文字驗證碼(Captcha)圖片
一、初始化Selenium動態網頁爬蟲專案
首先,前往博客來網站,點擊「會員登入」,如下:
截取自博客來網路書店官網
複製登入頁面的網址,如下:
截取自博客來網路書店登入畫面
接著,建立Python網頁爬蟲檔案,引用Selenium相關的模組,如下:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By import time import base64
其中,各個模組的引用時機及原因可以參考我之前寫的全面掌握Selenium建置動態網頁爬蟲的步驟與重要模組文章。
再來,就可以建立瀏覽器驅動物件,發送請求到博客來網站的登入頁面,如下範例第8~9行:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By import time import base64 browser = webdriver.Chrome(ChromeDriverManager().install()) browser.get('https://cart.books.com.tw/member/login')
二、Selenium下載文字驗證碼(Captcha)圖片
回到博客來網站,在文字驗證碼(Captcha)圖片的地方點擊滑鼠右鍵,選擇「檢查」,可以看到它的網頁原始碼如下:
點擊滑鼠右鍵,選擇「Copy / Copy XPath」,使用XPath的方式來定位網頁圖片,如下:
開啟Python網頁爬蟲檔案,利用time模組等待5秒的時間,讓網頁載入文字驗證碼(Captcha)圖片完成後,就可以透過Selenium套件的execute_script()方法,執行擷取網頁圖片的JavaScript程式碼,如下範例:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By import time import base64 browser = webdriver.Chrome(ChromeDriverManager().install()) browser.get('https://cart.books.com.tw/member/login') time.sleep(5) img_base64 = browser.execute_script(""" var ele = arguments[0]; var cnv = document.createElement('canvas'); cnv.width = ele.width; cnv.height = ele.height; cnv.getContext('2d').drawImage(ele, 0, 0); return cnv.toDataURL('image/jpeg').substring(22); """, browser.find_element(By.XPATH, "//*[@id='captcha_img']/img"))
第13~19行的JavaScript程式碼簡單來說,就是先定位畫面上的文字驗證碼(Captcha)圖片,接著,建立一個畫布(canvas),將文字驗證碼(Captcha)繪製上去後,並且進行base64編碼。
三、儲存文字驗證碼(Captcha)圖片
有了文字驗證碼(Captcha)圖片的base64編碼之後,就可以利用base64模組的b64decode()方法解碼,寫入本地端的圖片檔(captcha_login.png)來進行儲存的動作,如下範例第21~22行:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By import time import base64 browser = webdriver.Chrome(ChromeDriverManager().install()) browser.get('https://cart.books.com.tw/member/login') time.sleep(10) img_base64 = browser.execute_script(""" var ele = arguments[0]; var cnv = document.createElement('canvas'); cnv.width = ele.width; cnv.height = ele.height; cnv.getContext('2d').drawImage(ele, 0, 0); return cnv.toDataURL('image/jpeg').substring(22); """, browser.find_element(By.XPATH, "//*[@id='captcha_img']/img")) with open("captcha_login.png", 'wb') as image: image.write(base64.b64decode(img_base64))
執行之後就可以看到下載下來的文字驗證碼(Captcha)圖片,跟網頁上的是一樣的。
四、小結
這邊文章教大家學會使用Selenium套件動態下載網頁上的文字驗證碼(Captcha)圖片,接下來,就可以參考Selenium動態網頁爬蟲通過Captcha驗證碼的實用技巧文章,串接驗證碼辨識的服務,回填正確的文字驗證碼,通過反爬蟲機制,爬取想要的網頁資料。
你可能有興趣的文章
留言
張貼留言