python网络爬虫系列(九)——打码平台的使用
驗證碼處理
學習目標
1.圖片驗證碼
1.1 什么是圖片驗證碼
- 驗證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區分計算機和人類的圖靈測試)的縮寫,是一種區分用戶是計算機還是人的公共全自動程序。
1.2 驗證碼的作用
- 防止惡意破解密碼、刷票、論壇灌水、刷頁。有效防止某個黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登錄嘗試,實際上使用驗證碼是現在很多網站通行的方式(比如招商銀行的網上個人銀行,百度社區),我們利用比較簡易的方式實現了這個功能。雖然登錄麻煩一點,但是對網友的密碼安全來說這個功能還是很有必要,也很重要。
1.3 圖片驗證碼在爬蟲中的使用場景
- 注冊
- 登錄
- 頻繁發送請求時,服務器彈出驗證碼進行驗證
1.4 圖片驗證碼的處理方案
- 手動輸入(input)
這種方法僅限于登錄一次就可持續使用的情況 - 圖像識別引擎解析
使用光學識別引擎處理圖片中的數據,目前常用于圖片數據提取,較少用于驗證碼處理 - 打碼平臺
爬蟲常用的驗證碼解決方案
2.圖片識別引擎
OCR(Optical Character Recognition)是指使用掃描儀或數碼相機對文本資料進行掃描成圖像文件,然后對圖像文件進行分析處理,自動識別獲取文字信息及版面信息的軟件。
2.1 什么是tesseract
- Tesseract,一款由HP實驗室開發由Google維護的開源OCR引擎,特點是開源,免費,支持多語言,多平臺。
- 項目地址:https://github.com/tesseract-ocr/tesseract
- 下載地址:https://digi.bib.uni-mannheim.de/tesseract/
- 參考博文:https://blog.csdn.net/jacke121/article/details/76038663
2.2 圖片識別引擎環境的安裝
1 引擎的安裝
- mac環境下直接執行命令
-
windows環境下的安裝
可以通過exe安裝包安裝,下載地址可以從GitHub項目中的wiki找到。安裝完成后記得將Tesseract 執行文件的目錄加入到PATH中,方便后續調用。 -
linux環境下的安裝
2 Python庫的安裝
# PIL用于打開圖片文件 pip/pip3 install pillow# pytesseract模塊用于從圖片中解析數據 pip/pip3 install pytesseract2.3 圖片識別引擎的使用
- 通過pytesseract模塊的 image_to_string 方法就能將打開的圖片文件中的數據提取成字符串數據,具體方法如下
2.4 圖片識別引擎的使用擴展
- tesseract簡單使用與訓練
- 其他ocr平臺
3 打碼平臺
1.為什么需要了解打碼平臺的使用
現在很多網站都會使用驗證碼來進行反爬,所以為了能夠更好的獲取數據,需要了解如何使用打碼平臺爬蟲中的驗證碼
2 常見的打碼平臺
云打碼:http://www.yundama.com/
能夠解決通用的驗證碼識別
極驗驗證碼智能識別輔助:http://jiyandoc.c2567.com/
能夠解決復雜驗證碼的識別
3 云打碼的使用
下面以云打碼為例,了解打碼平臺如何使用
3.1 云打碼官方接口
下面代碼是云打碼平臺提供,做了個簡單修改,實現了兩個方法:
其中需要自己配置的地方是:
username = 'whoarewe' # 用戶名password = '***' # 密碼appid = 4283 # appidappkey = '02074c64f0d0bb9efb2df455537b01c3' # appkeycodetype = 1004 # 驗證碼類型云打碼官方提供的api如下:
#yundama.py import requests import json import timeclass YDMHttp:apiurl = 'http://api.yundama.com/api.php'username = ''password = ''appid = ''appkey = ''def __init__(self, username, password, appid, appkey):self.username = usernameself.password = passwordself.appid = str(appid)self.appkey = appkeydef request(self, fields, files=[]):response = self.post_url(self.apiurl, fields, files)response = json.loads(response)return responsedef balance(self):data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid,'appkey': self.appkey}response = self.request(data)if (response):if (response['ret'] and response['ret'] < 0):return response['ret']else:return response['balance']else:return -9001def login(self):data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid,'appkey': self.appkey}response = self.request(data)if (response):if (response['ret'] and response['ret'] < 0):return response['ret']else:return response['uid']else:return -9001def upload(self, filename, codetype, timeout):data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid,'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)}file = {'file': filename}response = self.request(data, file)if (response):if (response['ret'] and response['ret'] < 0):return response['ret']else:return response['cid']else:return -9001def result(self, cid):data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid,'appkey': self.appkey, 'cid': str(cid)}response = self.request(data)return response and response['text'] or ''def decode(self, filename, codetype, timeout):cid = self.upload(filename, codetype, timeout)if (cid > 0):for i in range(0, timeout):result = self.result(cid)if (result != ''):return cid, resultelse:time.sleep(1)return -3003, ''else:return cid, ''def post_url(self, url, fields, files=[]):# for key in files:# files[key] = open(files[key], 'rb');res = requests.post(url, files=files, data=fields)return res.text username = 'whoarewe' # 用戶名password = '***' # 密碼appid = 4283 # appidappkey = '02074c64f0d0bb9efb2df455537b01c3' # appkeyfilename = 'getimage.jpg' # 文件位置codetype = 1004 # 驗證碼類型# 超時 timeout = 60def indetify(response_content):if (username == 'username'):print('請設置好相關參數再測試')else:# 初始化yundama = YDMHttp(username, password, appid, appkey)# 登陸云打碼uid = yundama.login();print('uid: %s' % uid)# 查詢余額balance = yundama.balance();print('balance: %s' % balance)# 開始識別,圖片路徑,驗證碼類型ID,超時時間(秒),識別結果cid, result = yundama.decode(response_content, codetype, timeout)print('cid: %s, result: %s' % (cid, result))return resultdef indetify_by_filepath(file_path):if (username == 'username'):print('請設置好相關參數再測試')else:# 初始化yundama = YDMHttp(username, password, appid, appkey)# 登陸云打碼uid = yundama.login();print('uid: %s' % uid)# 查詢余額balance = yundama.balance();print('balance: %s' % balance)# 開始識別,圖片路徑,驗證碼類型ID,超時時間(秒),識別結果cid, result = yundama.decode(file_path, codetype, timeout)print('cid: %s, result: %s' % (cid, result))return resultif __name__ == '__main__':pass4 常見的驗證碼的種類
4.1 url地址不變,驗證碼不變
這是驗證碼里面非常簡單的一種類型,對應的只需要獲取驗證碼的地址,然后請求,通過打碼平臺識別即可
4.2 url地址不變,驗證碼變化
這種驗證碼的類型是更加常見的一種類型,對于這種驗證碼,大家需要思考:
在登錄的過程中,假設我輸入的驗證碼是對的,對方服務器是如何判斷當前我輸入的驗證碼是顯示在我屏幕上的驗證碼,而不是其他的驗證碼呢?
在獲取網頁的時候,請求驗證碼,以及提交驗證碼的時候,對方服務器肯定通過了某種手段驗證我之前獲取的驗證碼和最后提交的驗證碼是同一個驗證碼,那這個手段是什么手段呢?
很明顯,就是通過cookie來實現的,所以對應的,在請求頁面,請求驗證碼,提交驗證碼的到時候需要保證cookie的一致性,對此可以使用requests.session來解決
小結
總結
以上是生活随笔為你收集整理的python网络爬虫系列(九)——打码平台的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python网络爬虫系列(六)——数据提
- 下一篇: recv发送失败 缓冲区太小_从 GFS