1、導語 大家好,好久不見。又到每日分享Python小技能的時候了。最近因為疫情影響,所以更新內容比較慢…今天周一,就來更新一波,心血來潮,是時候上線經營了。其實也沒想到有啥好分享的,不如分享一些乾貨給大家,今天就分享一下如何識別圖片驗證碼併發送手機驗證碼的思路和代碼(基於python,對於過程中的 ...
1、導語
大家好,好久不見。又到每日分享Python小技能的時候了。最近因為疫情影響,所以更新內容比較慢…今天周一,就來更新一波,心血來潮,是時候上線經營了。其實也沒想到有啥好分享的,不如分享一些乾貨給大家,今天就分享一下如何識別圖片驗證碼併發送手機驗證碼的思路和代碼(基於python,對於過程中的涉及的瀏覽器技術原理我不過多贅述,不懂且想瞭解的小伙伴請自行搜索學習)。
2、目錄
首先,我們的程式分為三部分:
1、代理部分(防止頻繁請求被封,非必須)
2、識別部分(主要是某些驗證碼識別網站的demo,自己下載後進行相應改進)
3、執行部分
3、選擇例子
選取一個網站作為例子,例如這個網站,它的驗證形式為圖片驗證碼驗證,且圖片比較複雜,對打碼平臺的要求較高:
我們打開開發者模式,切換到network視窗,手動輸入手機號碼,並輸入圖片驗證碼的內容,點擊發送,進行抓包分析(框出或者標識部分都是重要部分,由於部分欄位涉及個人及網站隱私安全,已做馬賽克處理):
上面就是我們模擬發送簡訊驗證碼抓到的包,這個表單數據(form data)還是相對簡單,除了phone(輸入的手機號)和Verify(輸入的圖片驗證碼)是變化的,其他都是固定格式。有些相對複雜的,會有其他的加密方式,如md5對手機號加某些信息加密後傳輸,這些往往需要我們進行js解析(此處不過多贅述,請自行瞭解)。現在我們要做的就是識別驗證碼後將數據傳入並模擬發送,話不多說,我們開始。
4、代理部分
什麼代理:
代理伺服器(Proxy Server)的功能是代理網路用戶去取得網路信息。形象地說,它是網路信息的中轉站,是個人網路和Internet服務商之間的中間代理機構,負責轉發合法的網路信息,對轉發進行控制和登記。
代理伺服器作為連接Internet與Intranet的橋梁,在實際應用中發揮著極其重要的作用,它可用於多個目的,最基本的功能是連接,此外還包括安全性、緩存、內容過濾、訪問控制管理等功能。更重要的是,代理伺服器是Internet鏈路級網關所提供的一種重要的安全功能,它的工作主要在開放系統互聯(OSI)模型的對話層。
(更多詳情,如專享ip、隧道ip這些請自行瞭解)
我們這裡做代理ip,主要是為了安全起見,由於我們的頻繁訪問,網站管理者發現異常後極有可能將我們的ip封禁,所以我們需要使用代理ip,通過代理ip作為橋梁去訪問。
市面上有很多的代理ip提供,有免費的、收費的,當然,免費的代理ip體驗上是很差的,很多都不能用。我們自己可以去購買一些網站的套餐使用會流暢很多。至於哪家網站的代理ip好用,可以自行查找相關信息。我這裡使用的是 芝麻HTTP。
為了使代碼看起來更簡單,我使用單個ip進行演示,代碼如下:
#proxy.pyproxy = '113.128.28.102:4231'proxies = { 'http':'http://'+proxy}
5、識別部分
識別驗證碼我們仍然使用的是第三方的網站的代碼,python有Tesseract-OCR模塊供識別圖片,但識別率低。
市面上很多打碼平臺,識別率最好的是超級鷹,但收費較貴。其他的還有 圖鑒、斐斐打碼 之類的平臺,收費較為親民,但識別率不是很高。
對於我們這個例子,驗證碼較為複雜,一般的打碼平臺識別不出,所以我們選擇使用超級鷹。
對於這類的打碼平臺,我們一般是註冊充值後,複製他們提供的demo代碼,將賬號信息填入使用。每次使用需要下載圖片驗證碼到本地,由於驗證碼具有時效性,每次訪問都會變化,我們為了保證兩次訪問一致,主要保證兩次訪問的cookies一致。
代碼如下:
####Python學習交流群:906715085#### !/usr/bin/env python# coding:utf-8 #這個代碼是超級鷹提供的demo的基礎上,本人為了方便調用自行改造後的代碼 import osfrom proxy import proxiesimport requestsfrom hashlib import md5headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'}class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username password = password.encode('utf8') self.password = md5(password).hexdigest() self.soft_id = soft_id self.base_params = { 'user': self.username, 'pass2': self.password, 'softid': self.soft_id, } self.headers = { 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', } def PostPic(self, im, codetype): """ im: 圖片位元組 codetype: 題目類型 參考 http://www.chaojiying.com/price.html """ params = { 'codetype': codetype, } params.update(self.base_params) files = {'userfile': ('ccc.jpg', im)} r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) return r.json() def ReportError(self, im_id): """ im_id:報錯題目的圖片ID """ params = { 'id': im_id, } params.update(self.base_params) r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) return r.json() def main(imgPath,CodeType): #這一行填寫自己在超級鷹官網的賬號信息,記得把我在代碼標的中文替換 chaojiying = Chaojiying_Client('賬號', '密碼', '校驗碼') im = open(imgPath, 'rb').read() res=chaojiying.PostPic(im, CodeType) code=res['pic_str'] return code #imgDispose這一函數是執行代碼和識別代碼之間調用的橋梁,不使用代理請將 ,proxies=proxies 刪除def imgDispose(img_url,val): response=requests.get(url=img_url,headers=headers,proxies=proxies) img_data=response.content cookies=response.cookies.get_dict() #每次識別先將圖片保存到本地,識別完刪除 with open('img\CJYcodeImg.png',mode='wb') as f: f.write(img_data) code = main('img\CJYcodeImg.png', val) os.remove('img\CJYcodeImg.png') return code,cookies
6、執行部分
執行部分會用到我們抓包的信息,並相關信息填對就行,請自行舉一反三。
mport reimport time import chaojiyingDemofrom proxy import proxiesimport requests phoneNumber='手機號' headers2={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'}userAgent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'def identify(code_url,typeId,sendCode_url,headers,data,dataCode,funcName): try: result=chaojiyingDemo.imgDispose(code_url,typeId) imgCode=result[0] cookies=result[1] data[dataCode]=imgCode response = requests.post(url=sendCode_url,headers=headers,cookies=cookies,data=data, proxies=proxies, timeout=10) return '函數'+funcName+' 執行返回的結果為>>>>>>'+response.content.decode('utf-8') except Exception as e: return '函數' + funcName + ' 發生錯誤!' + str(e.args)def cjy2():#上學吧 headers = { 'Accept': 'text/plain, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Content-Length': '60', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': '', 'Origin': '', 'Referer': '', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"', 'sec-ch-ua-mobile': '?0', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'User-Agent': userAgent, 'X-Requested-With': 'XMLHttpRequest' } data={ 'phone': phoneNumber, 'dataid': '0', 'action': 'SMSSend', 'typeid': '0', } #6601是打碼平臺識別的驗證碼類型碼 identify('圖片驗證碼的url',6001,'發送的url(抓包得到的)',headers,data,'Verify','cjy2') cjy2()
7、最後
最近各地疫情爆發,大家一定要保護好自己。這一篇的小技巧還是比較簡單的,學會了就可以開始練練手了。碼代碼還是有點辛苦(點贊),到這裡就跟大家說再見了,不會的可以告訴我,我一般看見都會回覆。