用python登錄帶弱圖片驗(yàn)證碼的網(wǎng)站
上一篇介紹了使用python模擬登陸網(wǎng)站,但是登陸的網(wǎng)站都是直接輸入賬號(hào)及密碼進(jìn)行登陸,現(xiàn)在很多網(wǎng)站為了加強(qiáng)用戶安全性和提高反爬蟲(chóng)機(jī)制都會(huì)有包括字符、圖片、手機(jī)驗(yàn)證等等各式各樣的驗(yàn)證碼。圖片驗(yàn)證碼就是其中一種,而且識(shí)別難度越來(lái)越大,人為都比較難識(shí)別。本篇我們簡(jiǎn)單介紹一下使用python登陸帶弱圖片驗(yàn)證碼的網(wǎng)站。
圖片驗(yàn)證碼
一般都通過(guò)加干擾線、粘連或扭曲等方式來(lái)增加強(qiáng)度。

登陸
我們選擇一個(gè)政務(wù)網(wǎng)站(圖片驗(yàn)證碼的強(qiáng)度較低)。
點(diǎn)擊個(gè)人用戶登錄
訪問(wèn)網(wǎng)站首頁(yè)以后我們發(fā)現(xiàn)需要先點(diǎn)擊個(gè)人用戶登陸,且元素沒(méi)有name、id登標(biāo)識(shí)不好獲取,所以我們直接執(zhí)行里面的onClick方法


# 新建selenium瀏覽器對(duì)象,后面是geckodriver.exe下載后本地路徑
browser = webdriver.Firefox()
url = 'http://xxx.gov.cn/'
# 瀏覽器訪問(wèn)登錄頁(yè)面
browser.get(url)
# 等待3s用于加載腳本文件
browser.implicitly_wait(3)
# 點(diǎn)擊個(gè)人登陸
browser.execute_script('showpersonlogin();')
獲取圖片驗(yàn)證碼
我們可以通過(guò)save_screenshot截圖,然后找到驗(yàn)證碼元素,獲取元素位置然后在截圖的基礎(chǔ)上裁剪出驗(yàn)證碼。
# 找到圖片驗(yàn)證碼元素
img = browser.find_element_by_id('imgCode')
location = img.location
size = img.size
left = location['x']
top = location['y']
right = left + size['width']
bottom = top + size['height']
# 按照驗(yàn)證碼的長(zhǎng)寬,切割驗(yàn)證碼
image_obj = loginPage.crop((left, top, right, bottom))
image_obj.save('code.png')


識(shí)別并登陸
由于該網(wǎng)站的驗(yàn)證碼比較簡(jiǎn)單可以直接用pytesseract模塊的image_to_string方法
orcCode = pytesseract.image_to_string('code.png')
# 輸入用戶名
username = browser.find_element_by_id('personaccount')
username.send_keys('賬號(hào)')
# 輸入密碼
password = browser.find_element_by_id('personpassword')
password.send_keys('密碼')
# 輸入驗(yàn)證碼
code = browser.find_element_by_id('captcha1')
code.send_keys(orcCode)
# 執(zhí)行登錄
browser.execute_script('personlogin();')
# 關(guān)閉瀏覽器
# browser.quit()
識(shí)別較復(fù)雜驗(yàn)證碼算法
網(wǎng)上找的算法,先將圖片轉(zhuǎn)為灰度圖,然后進(jìn)行二值化處理(將圖像上的像素點(diǎn)的灰度值設(shè)置為0或255。如灰度大于等于閾值的像素,用255表示。否則為0。),再去噪(8鄰域降噪,判斷8個(gè)鄰域的黑色數(shù)量個(gè)數(shù))。
ocrImage.py:
import pytesseract
from PIL import Image
from collections import defaultdict
# 獲取圖片中像素點(diǎn)數(shù)量最多的像素
def get_threshold(image):
pixel_dict = defaultdict(int)
# 像素及該像素出現(xiàn)次數(shù)的字典
rows, cols = image.size
for i in range(rows):
for j in range(cols):
pixel = image.getpixel((i, j))
pixel_dict[pixel] += 1
count_max = max(pixel_dict.values()) # 獲取像素出現(xiàn)出多的次數(shù)
pixel_dict_reverse = {v: k for k, v in pixel_dict.items()}
threshold = pixel_dict_reverse[count_max] # 獲取出現(xiàn)次數(shù)最多的像素點(diǎn)
return threshold
# 按照閾值進(jìn)行二值化處理
# threshold: 像素閾值
def get_bin_table(threshold):
# 獲取灰度轉(zhuǎn)二值的映射table
table = []
for i in range(256):
rate = 0.1 # 在threshold的適當(dāng)范圍內(nèi)進(jìn)行處理
if threshold * (1 - rate) <= i <= threshold * (1 + rate):
table.append(1)
else:
table.append(0)
return table
# 去掉二值化處理后的圖片中的噪聲點(diǎn)
def cut_noise(image):
rows, cols = image.size # 圖片的寬度和高度
change_pos = [] # 記錄噪聲點(diǎn)位置
# 遍歷圖片中的每個(gè)點(diǎn),除掉邊緣
for i in range(1, rows - 1):
for j in range(1, cols - 1):
# pixel_set用來(lái)記錄該店附近的黑色像素的數(shù)量
pixel_set = []
# 取該點(diǎn)的鄰域?yàn)橐栽擖c(diǎn)為中心的九宮格
for m in range(i - 1, i + 2):
for n in range(j - 1, j + 2):
if image.getpixel((m, n)) != 1: # 1為白色,0位黑色
pixel_set.append(image.getpixel((m, n)))
# 如果該位置的九宮內(nèi)的黑色數(shù)量小于等于4,則判斷為噪聲
if len(pixel_set) <= 4:
change_pos.append((i, j))
# 對(duì)相應(yīng)位置進(jìn)行像素修改,將噪聲處的像素置為1(白色)
for pos in change_pos:
image.putpixel(pos, 1)
return image # 返回修改后的圖片
# 識(shí)別圖片中的數(shù)字加字母
# 傳入?yún)?shù)為圖片路徑,返回結(jié)果為:識(shí)別結(jié)果
def ocr_img(img_path):
image = Image.open(img_path) # 打開(kāi)圖片文件
imgry = image.convert('L') # 轉(zhuǎn)化為灰度圖
# 獲取圖片中的出現(xiàn)次數(shù)最多的像素,即為該圖片的背景
max_pixel = get_threshold(imgry)
# 將圖片進(jìn)行二值化處理
table = get_bin_table(threshold=max_pixel)
out = imgry.point(table, '1')
# 去掉圖片中的噪聲(孤立點(diǎn))
out = cut_noise(out)
# 僅識(shí)別圖片中的數(shù)字
# text = pytesseract.image_to_string(out, config='digits')
# 識(shí)別圖片中的數(shù)字和字母
text = pytesseract.image_to_string(out)
# 去掉識(shí)別結(jié)果中的特殊字符
exclude_char_list = ' .:\\|\'\"?![],()~@#$%^&*_+-={};<>/¥'
text = ''.join([x for x in text if x not in exclude_char_list])
return text

ocrImage.ocr_img('data/0021.png')

其他
針對(duì)不同的圖片驗(yàn)證碼用的方法不盡相同,cv2模塊也提供了很多圖片的處理方法可以用于識(shí)別圖片驗(yàn)證碼。
如使用cv2的腐蝕和碰撞方法就可以對(duì)圖片進(jìn)行簡(jiǎn)單的處理。
干擾條件較多、識(shí)別難度大的則需要依靠機(jī)器學(xué)習(xí)來(lái)完成。
以上就是用python登錄帶弱圖片驗(yàn)證碼的網(wǎng)站的詳細(xì)內(nèi)容,更多關(guān)于python 登錄圖片驗(yàn)證碼的網(wǎng)站的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python中pandas.read_csv()函數(shù)的深入講解
這篇文章主要給大家介紹了關(guān)于python中pandas.read_csv()函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Mac中Python 3環(huán)境下安裝scrapy的方法教程
作為一名python爬蟲(chóng)愛(ài)好者,怎能不折騰下Scrapy?折騰了許久之后終于安裝到了mac中,所以下面這篇文章主要給大家介紹了關(guān)于Mac系統(tǒng)中Python 3環(huán)境下安裝scrapy的相關(guān)資料,文中將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),需要的朋友可以參考下。2017-10-10
Vision?Transformer圖像分類模型導(dǎo)論
這篇文章主要為大家介紹了Vision?Transformer圖像分類模型導(dǎo)論,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
django下創(chuàng)建多個(gè)app并設(shè)置urls方法
在本篇文章里小編給大家分享的是一篇關(guān)于django下創(chuàng)建多個(gè)app并設(shè)置urls方法,需要的朋友們可以參考學(xué)習(xí)下。2020-08-08
python登錄WeChat 實(shí)現(xiàn)自動(dòng)回復(fù)實(shí)例詳解
在本篇內(nèi)容里小編給大家整理的是關(guān)于python登錄WeChat 實(shí)現(xiàn)自動(dòng)回復(fù)的相關(guān)實(shí)例內(nèi)容以及知識(shí)點(diǎn)總結(jié),有興趣的朋友們參考下。2019-05-05
使用原生Python編寫Hadoop?MapReduce程序
在大數(shù)據(jù)處理領(lǐng)域,Hadoop?MapReduce是一個(gè)廣泛使用的框架,用于處理和生成大規(guī)模數(shù)據(jù)集,本文將使用原生Python編寫Hadoop?MapReduce程序,需要的可以參考下2025-02-02
wxPython學(xué)習(xí)之主框架實(shí)例
這篇文章主要介紹了wxPython學(xué)習(xí)之主框架應(yīng)用實(shí)例,以一個(gè)基礎(chǔ)的彈出窗體實(shí)例講述了wxPython主框架應(yīng)用程序的實(shí)現(xiàn)方法,需要的朋友可以參考下2014-09-09

