Python反爬機(jī)制-驗(yàn)證碼功能的具體實(shí)現(xiàn)過(guò)程
識(shí)別驗(yàn)證碼
? OCR(Optical Character Recognition)即光學(xué)字符識(shí)別技術(shù),專門用于對(duì)圖片文字進(jìn)行識(shí)別,并獲取文本。字符驗(yàn)證碼的特點(diǎn)就是驗(yàn)證碼中包含數(shù)字、字母或者摻雜著斑點(diǎn)與混淆曲線的圖片驗(yàn)證碼。識(shí)別此類驗(yàn)證碼,首先需要找到驗(yàn)證碼驗(yàn)證碼圖片在網(wǎng)頁(yè)HTML代碼中的位置,然后將驗(yàn)證碼下載,最后再通過(guò)OCR技術(shù)進(jìn)行驗(yàn)證碼的識(shí)別工作。
1. 字符驗(yàn)證碼
1.1 OCR環(huán)境
? Tesseract-OCR是一個(gè)免費(fèi)、開源的OCR引擎,通過(guò)該引擎可以識(shí)別圖片中的驗(yàn)證碼,搭建OCR的具體步驟如下:
? (1)這里以macOS操作系統(tǒng)為例,使用brew install安裝tesseract,命令如下:
liuxiaowei@MacBookAir ~ % brew install --with-training-tools tesseract # 同時(shí)安裝附加組件
安裝完畢后用如下命令測(cè)試,示例代碼如下:
liuxiaowei@MacBookAir ~ % tesseract -v tesseract 5.0.1 leptonica-1.82.0 libgif 5.2.1 : libjpeg 9d : libpng 1.6.37 : libtiff 4.3.0 : zlib 1.2.11 : libwebp 1.2.1 : libopenjp2 2.4.0 Found AVX2 Found AVX Found FMA Found SSE4.1 Found libarchive 3.5.2 zlib/1.2.11 liblzma/5.2.5 bz2lib/1.0.8 liblz4/1.9.3 libzstd/1.5.0 Found libcurl/7.77.0 SecureTransport (LibreSSL/2.8.3) zlib/1.2.11 nghttp2/1.42.0
? (2)安裝tesseract模塊,安裝命令如下:
pip install tesseract

說(shuō) 明
如果使用的的是Anaconda并在安裝tesseract模塊時(shí)出現(xiàn)錯(cuò)誤,可以使用如下命令:
conda install -c simonflueckiger tesseract
1.2 下載驗(yàn)證碼圖片
以下面地址對(duì)應(yīng)的網(wǎng)頁(yè)為例,下載網(wǎng)頁(yè)中的驗(yàn)證碼圖片,具體步驟如下:
測(cè)試頁(yè)面地址:http://sck.rjkflm.com:666/spider/word/
(1)使用瀏覽器打開測(cè)試網(wǎng)頁(yè)的地址,將顯示如下圖片所示的字符驗(yàn)證碼:

? (2)打開瀏覽器開發(fā)者工具,然后在HTML代碼中獲取驗(yàn)證碼圖片所在的位置,如下圖所示:

? (3) 對(duì)目標(biāo)網(wǎng)頁(yè)發(fā)送網(wǎng)絡(luò)請(qǐng)求,并在返回的HTML代碼中獲取圖片的下載地址,然后下載驗(yàn)證碼圖片。代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/15/22 7:47 PM
# 文件 :獲取HTML代碼中地址下載驗(yàn)證碼圖片.py
# IDE :PyCharm
# 導(dǎo)入網(wǎng)絡(luò)請(qǐng)求模塊
import requests
# 導(dǎo)入urllib.request模塊
import urllib.request
# 導(dǎo)入隨機(jī)請(qǐng)求頭
from fake_useragent import UserAgent
# 導(dǎo)入ssl,否則ssl驗(yàn)證錯(cuò)誤
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 導(dǎo)入解析HTML的模塊
from bs4 import BeautifulSoup
# 創(chuàng)建隨機(jī)請(qǐng)求頭
header = {'User-Agent':UserAgent().random}
# 網(wǎng)頁(yè)請(qǐng)求地址
url = 'http://sck.rjkflm.com:666/spider/word/'
# 發(fā)送網(wǎng)絡(luò)請(qǐng)求
resp = requests.get(url, header)
resp.encoding = 'utf-8'
# 解析HTML
html = BeautifulSoup(resp.text, 'html.parser')
src = html.find('img').get('src')
# 組合驗(yàn)證碼圖片請(qǐng)求地址
img_url = url+src
# 下載并設(shè)置圖片名稱
urllib.request.urlretrieve(img_url, 'code.png')程序運(yùn)行后項(xiàng)目文件夾中自動(dòng)生成驗(yàn)證碼圖片,結(jié)果如下圖:

1.3 識(shí)別驗(yàn)證碼
? 驗(yàn)證碼下載完成以后, 如果沒(méi)有安裝pillow模塊,需要通過(guò)“pip install pillow“命令安裝一下,如果tesserocr模塊沒(méi)安裝也要通過(guò)"pip install tesserocr"先安裝,然后導(dǎo)入tesserocr與Image模塊,再通過(guò)Image.open()方法打開驗(yàn)證碼圖片,接著通過(guò)tesserocr.image_to_text()函數(shù)識(shí)別圖片中的驗(yàn)證碼信息即可。示例代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 7:21 AM
# 文件 :識(shí)別圖中驗(yàn)證碼.py
# IDE :PyCharm
# 導(dǎo)入tesserocr模塊
import tesserocr
# 導(dǎo)入圖像處理模塊
from PIL import Image
# 打開驗(yàn)證碼圖片
img = Image.open('code.png')
# 將圖片中的驗(yàn)證碼轉(zhuǎn)換為文本
code = tesserocr.image_to_text(img)
print('驗(yàn)證碼為: ', code)程序運(yùn)行結(jié)果如下:
驗(yàn)證碼為: uuuc
Process finished with exit code 0
? OCR的識(shí)別技術(shù)雖然很強(qiáng)大,但是并不是所有的驗(yàn)證碼都可以這么輕松地識(shí)別出來(lái),如下圖所示的驗(yàn)證碼中就會(huì)摻雜很多干擾線條,那么在識(shí)別這樣的驗(yàn)證碼信息時(shí),就需要對(duì)驗(yàn)證碼圖片進(jìn)行相應(yīng)的處理并識(shí)別。

如果直接通過(guò)OCR識(shí)別,識(shí)別結(jié)果將會(huì)受到干擾線的影響,下面通過(guò)OCR直接識(shí)別測(cè)試一下效果。示例代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 8:23 AM
# 文件 :識(shí)別帶干擾線的驗(yàn)證碼.py
# IDE :PyCharm
import tesserocr # 導(dǎo)入tesserocr模塊
from PIL import Image # 導(dǎo)入圖像處理模塊
img =Image.open('code2.jpg') # 打開驗(yàn)證碼圖片
img = img.convert('L') # 將彩色圖片轉(zhuǎn)換為灰度圖片
img.show() # 顯示灰度圖片
code = tesserocr.image_to_text(img) # 將圖片中的驗(yàn)證碼轉(zhuǎn)換為文本
print('驗(yàn)證碼為:',code)? 程序運(yùn)行結(jié)果如下:
驗(yàn)證碼為: YSGN. # 多了一個(gè).
Process finished with exit code 0
? 通過(guò)以上測(cè)試發(fā)現(xiàn),直接通過(guò)OCR技術(shù)識(shí)別后的驗(yàn)證碼中多了一個(gè)‘.’,遇到此類情況手寫可以將彩色的驗(yàn)證碼圖片轉(zhuǎn)為灰度圖片在測(cè)試一下。示例代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 8:29 AM
# 文件 :將彩色驗(yàn)證碼圖片轉(zhuǎn)為灰度圖片測(cè)試.py
# IDE :PyCharm
import tesserocr # 導(dǎo)入tesserocr模塊
from PIL import Image # 導(dǎo)入圖像處理模塊
img =Image.open('code2.jpg') # 打開驗(yàn)證碼圖片
img = img.convert('L') # 將彩色圖片轉(zhuǎn)換為灰度圖片
img.show() # 顯示灰度圖片
code = tesserocr.image_to_text(img) # 將圖片中的驗(yàn)證碼轉(zhuǎn)換為文本
print('驗(yàn)證碼為:',code)? 程序運(yùn)行結(jié)果如下:
驗(yàn)證碼為: YSGN. # 依然多一個(gè)‘.‘
Process finished with exit code 0

接下來(lái)需要將轉(zhuǎn)為灰度的驗(yàn)證碼圖片進(jìn)行二值化處理,將驗(yàn)證碼二值化處理后再次通過(guò)OCR進(jìn)行識(shí)別。示例代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 8:38 AM
# 文件 :將驗(yàn)證碼圖片二值化處理.py
# IDE :PyCharm
import tesserocr # 導(dǎo)入tesserocr模塊
from PIL import Image # 導(dǎo)入圖像處理模塊
img =Image.open('code2.jpg') # 打開驗(yàn)證碼圖片
img = img.convert('L') # 將彩色圖片轉(zhuǎn)換為灰度圖片
t = 155 # 設(shè)置閥值
table = [] # 二值化數(shù)據(jù)的列表
for i in range(256): # 循環(huán)遍歷
if i <t:
table.append(0)
else:
table.append(1)
img = img.point(table,'1') # 將圖片進(jìn)行二值化處理
img.show() # 顯示處理后圖片
code = tesserocr.image_to_text(img) # 將圖片中的驗(yàn)證碼轉(zhuǎn)換為文本
print('驗(yàn)證碼為:',code) # 打印驗(yàn)證碼? 程序運(yùn)行后將自動(dòng)顯示二值化處理后的驗(yàn)證碼圖片

程序運(yùn)行結(jié)果如下:
驗(yàn)證碼為: YSGN
Process finished with exit code 0
說(shuō) 明
在識(shí)別以上具有干擾線的驗(yàn)證碼圖片時(shí),我們可以做一些灰度和二值化處理,這樣可以提高圖片的驗(yàn)證碼的識(shí)別度,如果二值化處理后還是無(wú)法識(shí)別到精確性,可以適當(dāng)?shù)纳舷抡{(diào)節(jié)二值化操作的闕值。
2. 第三方驗(yàn)證碼識(shí)別
? 針對(duì)OCR識(shí)別率和準(zhǔn)確度不高的缺點(diǎn),使用第三方驗(yàn)證碼識(shí)別平臺(tái)是一個(gè)不錯(cuò)的選擇,不僅可以解決驗(yàn)證碼識(shí)別率低低問(wèn)題,還可以提高驗(yàn)證碼識(shí)別的準(zhǔn)確度。第三方平臺(tái)識(shí)別驗(yàn)證碼非常簡(jiǎn)單,平臺(tái)提供了完善的API接口,根據(jù)平臺(tái)對(duì)應(yīng)的開發(fā)文檔即可完成快速開發(fā)的需求,但每次驗(yàn)證碼成功識(shí)別后平臺(tái)會(huì)收取少量費(fèi)用。
? 驗(yàn)證碼識(shí)別平臺(tái)一般分為兩種,分別是打碼平臺(tái)和AI開發(fā)者平臺(tái)。打碼平臺(tái)主要是由在線人員進(jìn)行驗(yàn)證碼的識(shí)別工作,然后在較短的時(shí)間內(nèi)返回結(jié)果。AI開發(fā)者平臺(tái)主要是由人工智能來(lái)進(jìn)行識(shí)別。例如,百度AI。
下面以打碼平臺(tái)為例,演示驗(yàn)證碼識(shí)別的具體過(guò)程。
? (1)在瀏覽器中打開打碼平臺(tái)網(wǎng)頁(yè)(http://www.chaojiying.com/),并且單擊首頁(yè)的“用戶注冊(cè)”按鈕,如圖所示:

(2) 然后在用戶中心頁(yè)面中填寫注冊(cè)賬號(hào)的基本信息。如下圖:

說(shuō) 明
賬號(hào)注冊(cè)完成以后可以聯(lián)系平臺(tái)的客服人員,申請(qǐng)免費(fèi)測(cè)試的題分。
(3) 賬號(hào)注冊(cè)完成以后,在網(wǎng)頁(yè)的頂部導(dǎo)航欄中選擇“開發(fā)文檔”,然后在常用開發(fā)語(yǔ)言示例下載中選擇“Python“語(yǔ)言,如下圖所示:

(4) 在Python語(yǔ)音Demo下載頁(yè)面中,查看注意事項(xiàng),然后單擊“點(diǎn)擊這里下載”超鏈接即可下載示例代碼,如圖所示:

(5)平臺(tái)提供的示例代碼中,已經(jīng)將所有需要用到的功能代碼進(jìn)行了封裝處理,封裝的代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 10:01 AM
# 文件 :平臺(tái)提供識(shí)別封裝代碼.py
# IDE :PyCharm
import requests # 網(wǎng)絡(luò)請(qǐng)求模塊
from hashlib import md5 # 加密
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username # 自己注冊(cè)的賬號(hào)
password = password.encode('utf8') # 自己注冊(cè)的密碼
self.password = md5(password).hexdigest()
self.soft_id = soft_id # 軟件id
self.base_params = { # 組合表單數(shù)據(jù)
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = { # 請(qǐng)求頭信息
'Connection': 'Keep-Alive',
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
def PostPic(self, im, codetype):
"""
im: 圖片字節(jié)
codetype: 題目類型 參考 http://www.chaojiying.com/price.html
params = {
'codetype': codetype,
params.update(self.base_params) # 更新表單參數(shù)
files = {'userfile': ('code2.jpg', im)} # 上傳驗(yàn)證碼圖片
# 發(fā)送網(wǎng)絡(luò)請(qǐng)求
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json() # 返回響應(yīng)數(shù)據(jù)
def ReportError(self, im_id):
im_id:報(bào)錯(cuò)題目的圖片ID
'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()
if __name__ == '__main__':
#用戶中心>>軟件ID 生成一個(gè)替換 96001
chaojiying = Chaojiying_Client('超級(jí)鷹用戶名', '超級(jí)鷹用戶名的密碼', '928939')
im = open('a.jpg', 'rb').read() #本地圖片文件路徑 來(lái)替換 a.jpg 有時(shí)WIN系統(tǒng)須要//
#1902 驗(yàn)證碼類型 官方網(wǎng)站>>價(jià)格體系 3.4+版 print 后要加()
print(chaojiying.PostPic(im, 1902))? (6)使用平臺(tái)示例代碼中所提供的驗(yàn)證碼圖片,運(yùn)行以上示例代碼,運(yùn)行結(jié)果如下:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '9168810337948200001', 'pic_str': '7261', 'md5': '345c80a5dba345c219cc8893f19b496c'}
Process finished with exit code 0
? 說(shuō) 明
程序運(yùn)行結(jié)果中pic_str對(duì)應(yīng)的值為返回的驗(yàn)證碼識(shí)別信息。
? 在發(fā)送識(shí)別驗(yàn)證碼的網(wǎng)絡(luò)請(qǐng)求時(shí),代碼中的“1902”表示驗(yàn)證碼的類型,該平臺(tái)所支持的常用驗(yàn)證碼類型如下表:
? 常用驗(yàn)證碼類型
驗(yàn)證碼類型驗(yàn)證碼描述1902常見4-6位英文數(shù)字1101-10201-20位英文數(shù)字2001-20071-7位純漢字3004-30121-12位純英文4004-41111-11位純數(shù)字5000不定長(zhǎng)漢字英文數(shù)字51088位英文數(shù)字(包含字符)5201拼音首字母,計(jì)算題,成語(yǔ)混合5211集裝箱號(hào)4位字母7位數(shù)字6001計(jì)算題6003復(fù)雜計(jì)算題
說(shuō) 明
表中之列出了比較常用的驗(yàn)證碼識(shí)別類型,詳細(xì)內(nèi)容可查驗(yàn)證碼平臺(tái)官網(wǎng)
3. 滑動(dòng)拼圖驗(yàn)證碼
? 滑動(dòng)拼圖驗(yàn)證碼是在滑動(dòng)驗(yàn)證碼的基礎(chǔ)上增加了滑動(dòng)距離的校驗(yàn),用戶需要將圖形滑塊滑動(dòng)至主圖空缺滑塊的位置,才能通過(guò)校驗(yàn)。下面通過(guò)案例測(cè)試,實(shí)現(xiàn)滑動(dòng)拼圖驗(yàn)證碼的自動(dòng)校驗(yàn)。測(cè)試網(wǎng)頁(yè)地址:http://sck.rjkflm.com:666/spider/jgsaw/
? (1) 使用瀏覽器打開測(cè)試頁(yè)的地址,將顯示如圖所示的滑動(dòng)拼圖驗(yàn)證碼。

(2) 打開瀏覽器開發(fā)者工具,單擊按鈕滑塊,然后在HTML代碼中依次獲取“按鈕滑塊”“圖形滑塊”以及“空缺滑塊”所對(duì)應(yīng)的HTML代碼標(biāo)簽所在的位置。
| 驗(yàn)證碼類型 | 驗(yàn)證碼描述 |
|---|---|
| 1902 | 常見4-6位英文數(shù)字 |
| 1101-1020 | 1-20位英文數(shù)字 |
| 2001-2007 | 1-7位純漢字 |
| 3004-3012 | 1-12位純英文 |
| 4004-4111 | 1-11位純數(shù)字 |
| 5000 | 不定長(zhǎng)漢字英文數(shù)字 |
| 5108 | 8位英文數(shù)字(包含字符) |
| 5201 | 拼音首字母,計(jì)算題,成語(yǔ)混合 |
| 5211 | 集裝箱號(hào)4位字母7位數(shù)字 |
| 6001 | 計(jì)算題 |
| 6003 | 復(fù)雜計(jì)算題 |

(3)驗(yàn)證成功后的按鈕滑塊”“圖形滑塊”以及“空缺滑塊”位置變化如下所示
# 圖形滑塊 <div class="verify" style="display: block; top: 30.2081px; background-position: -173.893px -30.2081px; left: 10px;"></div> # 按鈕滑塊 <span class="swiper" style="left: 0px;"></span>
? (4) 通過(guò)按鈕滑塊的left值可以確認(rèn)需要滑動(dòng)的距離,接下來(lái)只需要使用selenium框架模擬滑動(dòng)的工作即可。實(shí)現(xiàn)代碼如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 創(chuàng)建時(shí)間 :2/16/22 5:19 PM
# 文件 :使用selenium框架模擬滑動(dòng)圖塊.py
# IDE :PyCharm
from selenium import webdriver # 導(dǎo)入webdriver
import re # 導(dǎo)入正則模塊
driver = webdriver.Chrome() # 谷歌瀏覽器
driver.get('http://sck.rjkflm.com:666/spider/jigsaw/') # 啟動(dòng)網(wǎng)頁(yè)
swiper = driver.find_element_by_xpath(
'/html/body/div/div[2]/div[2]/span[1]') # 獲取按鈕滑塊
action = webdriver.ActionChains(driver) # 創(chuàng)建動(dòng)作
action.click_and_hold(swiper).perform() # 單擊并保證不松開
# 滑動(dòng)0距離,不松手,不執(zhí)行該動(dòng)作無(wú)法獲取圖形滑塊left值
action.move_by_offset(0,0).perform()
# 獲取圖形滑塊樣式
verify_style = driver.find_element_by_xpath(
'/html/body/div/div[2]/div[1]/div[1]').get_attribute('style')
# 獲取空缺滑塊樣式
verified_style = driver.find_element_by_xpath(
'/html/body/div/div[2]/div[1]/div[2]').get_attribute('style')
# 獲取空缺滑塊left值
verified_left =float(re.findall('left: (.*?)px;',verified_style)[0])
# 獲取圖形滑塊left值
verify_left =float(re.findall('left: (.*?)px;',verify_style)[0])
action.move_by_offset(verified_left-verify_left,0) # 滑動(dòng)指定距離
action.release().perform() # 松開鼠標(biāo)程序運(yùn)行如下圖顯示:

總 結(jié)

到此這篇關(guān)于Python反爬機(jī)制-驗(yàn)證碼的文章就介紹到這了,更多相關(guān)Python驗(yàn)證碼反爬內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python?使用第三方庫(kù)requests-toolbelt?上傳文件流的示例
這篇文章主要介紹了python?使用第三方庫(kù)requests-toolbelt?上傳文件流,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09
聊聊基于pytorch實(shí)現(xiàn)Resnet對(duì)本地?cái)?shù)據(jù)集的訓(xùn)練問(wèn)題
本文項(xiàng)目是使用Resnet模型來(lái)識(shí)別螞蟻和蜜蜂,其一共有三百九十六張的數(shù)據(jù),訓(xùn)練集只有兩百多張(數(shù)據(jù)集很?。?,運(yùn)行十輪后,分別對(duì)訓(xùn)練集和測(cè)試集在每一輪的準(zhǔn)確率,對(duì)pytorch實(shí)現(xiàn)Resnet本地?cái)?shù)據(jù)集的訓(xùn)練感興趣的朋友一起看看吧2022-03-03
pycharm 更改創(chuàng)建文件默認(rèn)路徑的操作
今天小編就為大家分享一篇pycharm 更改創(chuàng)建文件默認(rèn)路徑的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
詳解Python OpenCV圖像分割算法的實(shí)現(xiàn)
圖像分割是指根據(jù)灰度、色彩、空間紋理、幾何形狀等特征把圖像劃分成若干個(gè)互不相交的區(qū)域。本文就來(lái)和大家聊聊OpenCV的圖像分割算法及基于輪廓的字符分離,感興趣的可以了解一下2022-08-08
詳談Python3 操作系統(tǒng)與路徑 模塊(os / os.path / pathlib)
下面小編就為大家分享一篇詳談Python3 操作系統(tǒng)與路徑 模塊(os / os.path / pathlib),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
聊聊prod()與cumprod()區(qū)別cumsum()
這篇文章主要介紹了prod()與cumprod()區(qū)別cumsum(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05

