python爬蟲如何解決圖片驗證碼
之前剛開始做爬蟲的時候遇到過登錄驗證碼問題,看過很多帖子都沒有解決我的問題,發現大多數帖子都是治標不治本,於是想分享一下自己的解決方案。本次采用的網站是古詩文網,使用百度API,因為百度API免費!免費!免費!適合自己學習的時候使用。如果還沒有使用過百度API識別驗證碼的朋友可以看一下我的這個帖子。
以下案例采用的時古詩文網:登錄古詩文網,
1、selenium處理圖片驗證碼
先定位到驗證碼圖片,在獲取驗證碼圖片在頁面中的位置,使用save_screenshot截取頁面,再根據圖片的位置去截取驗證碼,最後通過接口識別文字獲取驗證碼,直接上代碼:
element = driver.find_element_by_id('imgCode') # 定位驗證碼圖片 # 獲取驗證碼圖片在網頁中的位置 left = int(element.location['x']) # 獲取圖片左上角坐標x top = int(element.location['y']) # 獲取圖片左上角y right = int(element.location['x'] + element.size['width']) # 獲取圖片右下角x bottom = int(element.location['y'] + element.size['height']) # 獲取圖片右下角y # 通過Image處理圖像 path = current_dir + str(random.random()) + '.png' # 生成隨機文件名 driver.save_screenshot(path) # 截取當前窗口並保存圖片 im = Image.open(path) # 打開圖片 im = im.crop((left, top, right, bottom)) # 截圖驗證碼 im.save(path) # 保存驗證碼圖片 # 使用百度API識別驗證碼 def get_code(): client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 百度API文檔中提供的方法識別文字 # 由於我處理的驗證碼圖片沒有填多的線條,所以直接采用灰度是驗證碼數字更加清晰,具體的處理方式可根據驗證碼的實際情況而定 im = Image.open(path) # 轉換為灰度圖像 im = im.convert('L') im.save(path) # 讀取圖片,應為百度API中提供的方法參數隻能是字節流 with open(path, 'rb')as f: image = f.read() # 使用API中提供的方法識別驗證碼並返回驗證碼 code = client.basicGeneral(image) print(code['words_result'][0]['words']) # {'words_result': [{'words': '4TBiD ', 'location': {'top': 1, 'left': 6, 'width': 43, 'height': 13}}], 'log_id': 1358288307112378368, 'words_result_num': 1} return code['words_result'][0]['words']
2、使用requests請求驗證碼
這裡用到瞭會話機制,對於初學者來說可能不太瞭解,簡單說一下會話機制的作用,會話就是用來保存你之前請求的cookie,讓瀏覽器知道你之前就在這裡,這樣瀏覽器就不會認為你重新來到這裡,從而刷新驗證碼,這樣就可以帶著我們獲取的驗證碼去登錄瞭。
conn = requests.Sessoin( # 創建會話 resp = conn.get('https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx') selector = Selector(text=resp.text) img_url = 'https://so.gushiwen.cn/'+selector.xpath('.//img[@id="imgCode"]/@src').get() # 獲取圖片的路由 img = conn.get(img_url) # 保持會話請求 filename = str(random.random()) + '.png' with open(filename, 'wb')as f: f.write(img.content) # 為瞭後面的調用接口識別不報圖片格式錯誤,進行一次圖片轉換 im = Image.open(filename) im.save(filename) # 使用二進制方式讀取圖片 with open(filename, 'rb')as f: image = f.read() data = client.handwriting(image) # diao'yong # 使用API中提供的方法識別驗證碼並返回驗證碼 code = client.basicGeneral(image) code = code['words_result'][0]['words']
selenium源碼
# -* coding: utf-8 *- import time import random from PIL import Image from aip import AipOcr from selenium.webdriver import Chrome # 百度API參數 APP_ID = '23647800' API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN' SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK' client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 調用API接口 def scrapy(username, password): """ :param username: 用戶名 :param password: 密碼 """ driver = Chrome() driver.get('https://so.gushiwen.cn/user/login.aspx') driver.find_element_by_id('email').send_keys(username) # 輸入賬號 driver.find_element_by_id('pwd').send_keys(password) # 輸入密碼 element = driver.find_element_by_id('imgCode') # 定位驗證碼圖片 # 獲取驗證碼圖片在網頁中的位置 left = int(element.location['x']) # 獲取圖片左上角坐標x top = int(element.location['y']) # 獲取圖片左上角y right = int(element.location['x'] + element.size['width']) # 獲取圖片右下角x bottom = int(element.location['y'] + element.size['height']) # 獲取圖片右下角y # 通過Image處理圖像 filename = str(random.random()) + '.png' # 生成隨機文件名 driver.save_screenshot(filename) # 截取當前窗口並保存圖片 im = Image.open(filename) # 打開圖片 im = im.crop((left, top, right, bottom)) # 截圖驗證碼 im.save(filename) # 保存驗證碼圖片 # 由於我處理的驗證碼圖片沒有填多的線條,所以直接采用灰度是驗證碼數字更加清晰,具體的處理方式可根據驗證碼的實際情況而定 im = Image.open(filename) # 轉換為灰度圖像 im = im.convert('L') im.save(filename) # 讀取圖片,應為百度API中提供的方法參數隻能是字節流 with open(filename, 'rb')as f: image = f.read() # 使用API中提供的方法識別驗證碼並返回驗證碼 data = client.basicGeneral(image) try: code = data['words_result'][0]['words'] except: return data['error_msg'] driver.find_element_by_id('code').send_keys(code) # 輸入驗證碼 driver.find_element_by_id('denglu').click() # 點擊登錄 time.sleep(1000) # 為瞭看清登錄,等待1000秒 if __name__ == '__main__': print(scrapy(username, password)) # 傳入你在古詩文網註冊的賬號密碼
requests源碼
# -* coding: utf-8 *- import os import random import re import requests from PIL import Image from aip import AipOcr from scrapy import Selector headers = { 'referer': 'https://so.gushiwen.cn/user/login.aspx', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36' } # 百度API參數 APP_ID = '23647800' API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN' SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK' def scrapy(username, password): """ :param username: 用戶名 :param password: 密碼 """ client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 調用API接口 conn = requests.Session() # 創建會話 resp = conn.get('https://so.gushiwen.cn/user/login.aspx', headers=headers) # 獲取登錄頁面 selector = Selector(text=resp.text) __VIEWSTATE = selector.xpath('.//input[@id="__VIEWSTATE"]/@value').get() __VIEWSTATEGENERATOR = selector.xpath('.//input[@id="__VIEWSTATEGENERATOR"]/@value').get() img_url = 'https://so.gushiwen.cn/' + selector.xpath('.//img[@id="imgCode"]/@src').get() # 獲取圖片的路由 img = conn.get(img_url, headers=headers) # 獲取圖片路由 # 保存圖片 filename = str(random.random()) + '.png' # 隨機生成文件名, 圖片格式不能為jpg,API不支持jpg格式的識別 with open(filename, 'wb')as f: f.write(img.content) # 由於我處理的驗證碼圖片沒有填多的線條,所以直接采用灰度是驗證碼數字更加清晰,具體的處理方式可根據驗證碼的實際情況而定 im = Image.open(filename) # 轉換為灰度圖像 im = im.convert('L') im.save(filename) # 使用二進制方式讀取圖片 with open(filename, 'rb')as f: image = f.read() # # 標準識別, 每天免費50000次 # data = client.basicGeneral(image) # 精確識別,每天免費500次 data = client.handwriting(image) # 捕獲一下接口識別當中的錯誤,可參照文檔查看報錯原因 try: code = data['words_result'][0]['words'] except: return data['error_msg'] form_data = { '__VIEWSTATE': __VIEWSTATE, '__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR, 'from': '', 'email': username, 'pwd': password, 'code':cod, 'denglu': '登錄' } # 登錄 html = conn.post('https://so.gushiwen.cn/user/login.aspx', headers=headers, data=form_data).text # 獲取登錄標志位 login_flag = re.findall("alert\('(.*?)'\);",html)[0] if re.findall("alert\('(.*?)'\);",html) else '' if not login_flag: return '登錄成功!' elif '驗證碼有誤!' in login_flag: return "驗證碼錯誤" if __name__ == '__main__': print(scrapy(username, password))
以上就是python爬蟲如何解決圖片驗證碼的詳細內容,更多關於python 解決圖片驗證碼的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- python簡單驗證碼識別的實現過程
- selenium+超級鷹實現模擬登錄12306
- Python爬蟲模擬登陸嗶哩嗶哩(bilibili)並突破點選驗證碼功能
- Python中常見的反爬機制及其破解方法總結
- python3定位並識別圖片驗證碼實現自動登錄功能