python自動化操作之動態(tài)驗證碼、滑動驗證碼的降噪和識別
前言
python對動態(tài)驗證碼、滑動驗證碼的降噪和識別,在各種自動化操作中,我們經(jīng)常要遇到沿跳過驗證碼的操作,而對于驗證碼的降噪和識別,的確困然了很多的人。這里我們就詳細(xì)講解一下不同驗證碼的降噪和識別。
一、動態(tài)驗證碼
- 動態(tài)驗證碼是服務(wù)端生成的,點擊一次,就會更換一次,這就會造成很多人在識別的時候,會發(fā)現(xiàn)驗證碼一直過期
- 這是因為,如果你是把圖片下載下來,進(jìn)行識別的話,其實在下載的這個請求中,其實相當(dāng)于點擊了一次,這個驗證碼的內(nèi)容已經(jīng)被更換了
- 最好的方法是,打開這個頁面后,將頁面進(jìn)行截圖,然后定位到驗證碼的位置,將驗證碼從截圖上面裁剪下來進(jìn)行識別,這樣就不會造成多次請求,驗證碼更換的情況了
from selenium import webdriver from PIL import Image # 實例化瀏覽器 driver = webdriver.Chrome() # 最大化窗口 driver.maximize_window() # 打開登陸頁面 driver.get(# 你的url地址) # 保存頁面截圖 driver.get_screenshot_as_file('./screen.png') # 定位驗證碼的位置 location = driver.find_element_by_id('login_yzm_img').location size = driver.find_element_by_id('login_yzm_img').size left = location['x'] top = location['y'] right = location['x'] + size['width'] bottom = location['y'] + size['height'] # 裁剪保存 img = Image.open('./screen.png').crop((left,top,right,bottom)) img.save('./code.png') driver.quit()
二、滑動驗證碼
- 滑動驗證碼,通常是兩個滑塊圖片,將小圖片滑動到大圖片上的缺口位置,進(jìn)行重合,即可通過驗證
- 對于滑動驗證碼,我們就要識別大圖上面的缺口位置,然后讓小滑塊滑動響應(yīng)的位置距離,即可
- 而為了讓你滑動起來,更加的擬人化,你需要一個滑動的路徑,模擬人為去滑動,而不是機(jī)器去滑動
# 下載兩個滑塊 bg = self.driver.find_element_by_xpath('//*[@id="captcha_container"]/div/div[2]/img[1]').get_attribute('src') slider = self.driver.find_element_by_xpath('//*[@id="captcha_container"]/div/div[2]/img[2]').get_attribute('src') request.urlretrieve(bg, os.getcwd() + '/bg.png') request.urlretrieve(slider, os.getcwd() + '/slider.png') # 獲取兩個滑塊偏移量方法 def getGap(self, sliderImage, bgImage): ''' Get the gap distance :param sliderImage: the image of slider :param bgImage: the image of background :return: int ''' bgImageInfo = cv2.imread(bgImage, 0) bgWidth, bgHeight = bgImageInfo.shape[::-1] bgRgb = cv2.imread(bgImage) bgGray = cv2.cvtColor(bgRgb, cv2.COLOR_BGR2GRAY) slider = cv2.imread(sliderImage, 0) sliderWidth, sliderHeight = slider.shape[::-1] res = cv2.matchTemplate(bgGray, slider, cv2.TM_CCOEFF) a, b, c, d = cv2.minMaxLoc(res) # print(a,b,c,d) # 正常如下即可 # return c[0] if abs(a) >= abs(b) else d[0] # 但是頭條顯示驗證碼的框跟驗證碼本身的像素不一致,所以需要根據(jù)比例計算 if abs(a) >= abs(b): return c[0] * bgWidth / (bgWidth - sliderWidth) else: return d[0] * bgWidth / (bgWidth - sliderWidth) # 移動路徑方法 def getTrack(self, distance): ''' Get the track by the distance :param distance: the distance of gap :return: list ''' # 移動軌跡 track = [] # 當(dāng)前位移 current = 0 # 減速閾值 mid = distance * 4 / 5 # 計算間隔 t = 0.2 # 初速度 v = 0 while current < distance: if current < mid: # 加速度為正2 a = 2 else: # 加速度為負(fù)3 a = -3 # 初速度v0 v0 = v # 當(dāng)前速度v = v0 + at v = v0 + a * t # 移動距離x = v0t + 1/2 * a * t^2 move = v0 * t + 1 / 2 * a * t * t # 當(dāng)前位移 current += move # 加入軌跡 track.append(round(move)) return track # 滑動到缺口位置 def moveToGap(self, track): ''' Drag the mouse to gap :param track: the track of mouse :return: None ''' ActionChains(self.driver).click_and_hold(self.driver.find_element_by_xpath('//*[@id="captcha_container"]/div/div[3]/div[2]/div[2]/div')).perform() while track: x = random.choice(track) ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform() track.remove(x) time.sleep(0.5) ActionChains(self.driver).release().perform()
三、驗證碼的降噪
驗證碼的降噪,只是為了處理驗證碼圖像上的多余的線條和干擾線,讓你后期識別更加的準(zhǔn)確,提高識別的準(zhǔn)確度
第一步:可以進(jìn)行灰度轉(zhuǎn)化
img = cv2.imread('yzm.png') # 將圖片灰度化處理,降維,加權(quán)進(jìn)行灰度化c gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) cv2.imshow('min_gray',gray) cv2.waitKey(0) cv2.destroyAllWindows()
第二步: 二值化處理
import cv2 img = cv2.imread('yzm.png') # 將圖片灰度化處理,降維,加權(quán)進(jìn)行灰度化c gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) t,gray2 = cv2.threshold(gray,220,255,cv2.THRESH_BINARY) cv2.imshow('threshold',gray2) cv2.waitKey(0) cv2.destroyAllWindows()
第三步:噪點過濾
import cv2 img = cv2.imread('yzm.png') # 將圖片灰度化處理,降維,加權(quán)進(jìn)行灰度化c gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) t,gray2 = cv2.threshold(gray,220,255,cv2.THRESH_BINARY) def remove_noise(img, k=4): img2 = img.copy() # img處理數(shù)據(jù),k過濾條件 w, h = img2.shape def get_neighbors(img3, r, c): count = 0 for i in [r - 1, r, r + 1]: for j in [c - 1, c, c + 1]: if img3[i, j] > 10: # 純白色 count += 1 return count # 兩層for循環(huán)判斷所有的點 for x in range(w): for y in range(h): if x == 0 or y == 0 or x == w - 1 or y == h - 1: img2[x, y] = 255 else: n = get_neighbors(img2, x, y) # 獲取鄰居數(shù)量,純白色的鄰居 if n > k: img2[x, y] = 255 return img2 result = remove_noise(gray2) cv2.imshow('8neighbors', result) cv2.waitKey(0) cv2.destroyAllWindows()
四、驗證碼的識別
通常我們會使用tesserocr識別驗證碼,但是這個庫有很大的局限性,識別率低,即時降噪效果很好,有很少的線條,也會不準(zhǔn)確,這種識別方式并不十分推薦
所以我們一般會使用第三方的接口進(jìn)行識別,比如阿里的圖片識別、騰訊也都是有的
這些第三方接口需要自己接入識別接口
#識別降噪后的圖片 code = tesserocr.image_to_text(nrImg) #消除空白字符 code.strip() #打印 print(code)
總結(jié)
到此這篇關(guān)于python自動化操作之動態(tài)驗證碼、滑動驗證碼的降噪和識別的文章就介紹到這了,更多相關(guān)python動態(tài)驗證碼降噪和識別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
初學(xué)python數(shù)學(xué)建模之?dāng)?shù)據(jù)導(dǎo)入(小白篇)
本篇文章是小白篇初學(xué)python的同學(xué)可以來共同學(xué)習(xí)了,本篇文章主要講解了python數(shù)學(xué)建模過程中的第一步數(shù)據(jù)導(dǎo)入,數(shù)據(jù)導(dǎo)入是所有數(shù)模編程的第一步,比你想象的更重要2021-08-08python?Sweetviz探索性數(shù)據(jù)可視化分析庫使用特征詳解
這篇文章主要為大家介紹了python?Sweetviz探索性數(shù)據(jù)可視化分析庫特征使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01對python當(dāng)中不在本路徑的py文件的引用詳解
今天小編就為大家分享一篇對python當(dāng)中不在本路徑的py文件的引用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12Django零基礎(chǔ)入門之調(diào)用漂亮的HTML前端頁面
這篇文章主要介紹了Django零基礎(chǔ)入門之調(diào)用漂亮的HTML前端頁面的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09Python實現(xiàn)pdf轉(zhuǎn)word詳細(xì)代碼
在日常工作中,我們經(jīng)常會遇到需要將PDF文件轉(zhuǎn)換成Word文件的需求。雖然市面上有許多PDF轉(zhuǎn)Word的工具,但是它們通常需要付費或者有轉(zhuǎn)換后的格式問題,這篇文章主要給大家介紹了關(guān)于Python實現(xiàn)pdf轉(zhuǎn)word的相關(guān)資料,需要的朋友可以參考下2023-09-09