python識別古老驗證碼

python識別古老驗證碼

來自專欄萌新的學習日記4 人贊了文章

需求:

pm平台登錄圖片驗證碼比較簡單,是否可以通過圖片識別來進行破解登錄呢?

思路:

圖片驗證碼怎麼來的,怎麼獲取到,獲取之後怎麼處理,處理得到的字元串怎麼知道是與登錄請求為同一個驗證碼,我們一個個問題來:

  • 圖片驗證碼怎麼來的:

使用chrome訪問:XXXXXX/pm/login,打開F12查看都有哪些請求:發現除了一些資源請求外,還有兩個請求,一個是login,一個是image_code:不難看出,一個是登錄請求,一個是驗證碼請求(每刷新一次頁面,就會發送一些獲取驗證碼請求),所以知道圖片驗證碼是通過訪問登錄後,驗證碼請求同時發送:

登錄:XXXXXX/pm/login

驗證碼:XXXXXX/pm/image_code

  • 如何獲取驗證碼:

通過驗證碼請求,我們可以獲取到驗證碼圖片,再把圖片保存到本地:

  • 獲取之後怎麼處理:

讀取上一步獲取到的驗證碼圖片,可以通過以下步驟對圖片進行處理:

  1. 置灰處理
  2. 二值化
  3. 去除邊框
  4. 干擾線降噪、點降噪處理
  5. 切割圖片
  6. 識別

對於本例而言,進行前三步就行了。因為驗證碼比較簡單。直接上代碼:

def im_code(): """ 識別圖片驗證碼 :return: """ # 新建Image對象 im = Image.open(r.easy_img1image.jpeg) # 進行置灰處理 im = im.convert(L) # 二值化閾值 threshold = 150 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) # 通過表格轉換成二進位圖片,1的作用是白色 im = im.point(table, 1) result = tesserocr.image_to_text(im).strip() return result

  • 處理得到的字元串怎麼知道是與登錄請求為同一個驗證碼:

通過上一步,有一定概率可以獲取到驗證碼(圖片識別都是概率的),到這裡,就會有一個問題,我們獲取的驗證碼與登錄時的驗證碼是一樣的嗎?這時就需要清楚一個原理,先發送驗證碼請求,再發送登錄請求,只要兩個請求的session一樣,驗證碼是生效的。這就知道知道python requests模塊session()自動保存原理。

總結:

明白了上面說的幾個問題後,來總結一下思路:通過驗證碼請求獲取圖片保存到本地->通過圖片處理模塊處理得到的圖片->把獲取到的驗證碼字元串用於登錄,循環整個過程,成功得返回cookies:

代碼:

注意:tesseror模塊的安裝,需要在pypi下載對應版本:tesserocr-2.2.2-cp35-cp35m-win_amd64.whl

import requestsimport tesserocrfrom PIL import Imageclass PmLogin: """ pm獲取驗證碼並登錄 """ def __init__(self): # sessoin對象創建 self.sess = requests.session() # 請求頭定義 self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36", "Connection": "keep-alive"} # cookies定義 self.cookies = None def downimage(self, i): """ 獲取驗證碼,保存到指定文件夾中 :param i: 獲取次數 :return: """ url = "http://xxxxxx/pm/image_code" image = self.sess.get(url, headers=self.headers).content with open(r./easy_img/ + str(i) + "image.jpeg", "wb") as f: f.write(image) def im_code(self): """ 識別圖片驗證碼 :return: """ # 新建Image對象 im = Image.open(r.easy_img1image.jpeg) # 進行置灰處理 im = im.convert(L) # 二值化閾值 threshold = 150 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) # 通過表格轉換成二進位圖片,1的作用是白色 im = im.point(table, 1) result = tesserocr.image_to_text(im).strip() return result def pm_login(self, code): """ 登錄請求,使用獲取到的驗證碼來進行登錄,判斷登錄是否成功,成功返回True,失敗返回False :param code: :return: """ url = "http://xxxxxx/pm/login" print(code) data = {"pre_page": "", "username": "zhusi", "password": "111111", "imageCode": code} resp = self.sess.post(url, headers=self.headers, data=data) self.cookies = requests.utils.dict_from_cookiejar(self.sess.cookies) self.cookies = dict(self.cookies) # print(self.cookies) if "session_user" in self.cookies.keys(): return True else: return Falseif __name__ == __main__: # 循環獲取驗證碼並登錄 for i in range(20): # 創建類的對象 t = PmLogin() # 獲取圖片驗證碼 t.downimage(1) # 獲取處理後的圖片,得到驗證碼字元串 code = t.im_code() # 調用pm_login(code)方法,傳入驗證碼,通過cookies判斷是否登錄成功 if t.pm_login(code): # 登錄成功,列印cookies並跳出循環 print(t.cookies) break

運行結果可以看到,已經獲取到了session:


推薦閱讀:

ubuntu建立虛擬環境,並在虛擬環境下創建django項目
超乎想像的format函數用法
[Python學習] Django 許可權控制
572. Subtree of Another Tree
用python爬取B站彈幕並製作詞雲

TAG:爬蟲計算機網路 | Python | 驗證碼 |