之前剛開始做爬蟲的時(shí)候遇到過登錄驗(yàn)證碼問題,看過很多帖子都沒有解決我的問題,發(fā)現(xiàn)大多數(shù)帖子都是治標(biāo)不治本,于是想分享一下自己的解決方案。本次采用的網(wǎng)站是古詩文網(wǎng),使用百度API,因?yàn)榘俣華PI免費(fèi)!免費(fèi)!免費(fèi)!適合自己學(xué)習(xí)的時(shí)候使用。如果還沒有使用過百度API識別驗(yàn)證碼的朋友可以看一下我的這個(gè)帖子。
以下案例采用的時(shí)古詩文網(wǎng):登錄古詩文網(wǎng),
1、selenium處理圖片驗(yàn)證碼
先定位到驗(yàn)證碼圖片,在獲取驗(yàn)證碼圖片在頁面中的位置,使用save_screenshot截取頁面,再根據(jù)圖片的位置去截取驗(yàn)證碼,最后通過接口識別文字獲取驗(yàn)證碼,直接上代碼:
element = driver.find_element_by_id('imgCode') # 定位驗(yàn)證碼圖片
# 獲取驗(yàn)證碼圖片在網(wǎng)頁中的位置
left = int(element.location['x']) # 獲取圖片左上角坐標(biāo)x
top = int(element.location['y']) # 獲取圖片左上角y
right = int(element.location['x'] + element.size['width']) # 獲取圖片右下角x
bottom = int(element.location['y'] + element.size['height']) # 獲取圖片右下角y
# 通過Image處理圖像
path = current_dir + str(random.random()) + '.png' # 生成隨機(jī)文件名
driver.save_screenshot(path) # 截取當(dāng)前窗口并保存圖片
im = Image.open(path) # 打開圖片
im = im.crop((left, top, right, bottom)) # 截圖驗(yàn)證碼
im.save(path) # 保存驗(yàn)證碼圖片
# 使用百度API識別驗(yàn)證碼
def get_code():
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 百度API文檔中提供的方法識別文字
# 由于我處理的驗(yàn)證碼圖片沒有填多的線條,所以直接采用灰度是驗(yàn)證碼數(shù)字更加清晰,具體的處理方式可根據(jù)驗(yàn)證碼的實(shí)際情況而定
im = Image.open(path)
# 轉(zhuǎn)換為灰度圖像
im = im.convert('L')
im.save(path)
# 讀取圖片,應(yīng)為百度API中提供的方法參數(shù)只能是字節(jié)流
with open(path, 'rb')as f:
image = f.read()
# 使用API中提供的方法識別驗(yàn)證碼并返回驗(yàn)證碼
code = client.basicGeneral(image)
print(code['words_result'][0]['words']) # {'words_result': [{'words': '4TBiD ', 'location': {'top': 1, 'left': 6, 'width': 43, 'height': 13}}], 'log_id': 1358288307112378368, 'words_result_num': 1}
return code['words_result'][0]['words']
2、使用requests請求驗(yàn)證碼
這里用到了會話機(jī)制,對于初學(xué)者來說可能不太了解,簡單說一下會話機(jī)制的作用,會話就是用來保存你之前請求的cookie,讓瀏覽器知道你之前就在這里,這樣瀏覽器就不會認(rèn)為你重新來到這里,從而刷新驗(yàn)證碼,這樣就可以帶著我們獲取的驗(yàn)證碼去登錄了。
conn = requests.Sessoin( # 創(chuàng)建會話
resp = conn.get('https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx')
selector = Selector(text=resp.text)
img_url = 'https://so.gushiwen.cn/'+selector.xpath('.//img[@id="imgCode"]/@src').get() # 獲取圖片的路由
img = conn.get(img_url) # 保持會話請求
filename = str(random.random()) + '.png'
with open(filename, 'wb')as f:
f.write(img.content)
# 為了后面的調(diào)用接口識別不報(bào)圖片格式錯(cuò)誤,進(jìn)行一次圖片轉(zhuǎn)換
im = Image.open(filename)
im.save(filename)
# 使用二進(jìn)制方式讀取圖片
with open(filename, 'rb')as f:
image = f.read()
data = client.handwriting(image) # diao'yong
# 使用API中提供的方法識別驗(yàn)證碼并返回驗(yàn)證碼
code = client.basicGeneral(image)
code = code['words_result'][0]['words']
selenium源碼
# -* coding: utf-8 *-
import time
import random
from PIL import Image
from aip import AipOcr
from selenium.webdriver import Chrome
# 百度API參數(shù)
APP_ID = '23647800'
API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN'
SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 調(diào)用API接口
def scrapy(username, password):
"""
:param username: 用戶名
:param password: 密碼
"""
driver = Chrome()
driver.get('https://so.gushiwen.cn/user/login.aspx')
driver.find_element_by_id('email').send_keys(username) # 輸入賬號
driver.find_element_by_id('pwd').send_keys(password) # 輸入密碼
element = driver.find_element_by_id('imgCode') # 定位驗(yàn)證碼圖片
# 獲取驗(yàn)證碼圖片在網(wǎng)頁中的位置
left = int(element.location['x']) # 獲取圖片左上角坐標(biāo)x
top = int(element.location['y']) # 獲取圖片左上角y
right = int(element.location['x'] + element.size['width']) # 獲取圖片右下角x
bottom = int(element.location['y'] + element.size['height']) # 獲取圖片右下角y
# 通過Image處理圖像
filename = str(random.random()) + '.png' # 生成隨機(jī)文件名
driver.save_screenshot(filename) # 截取當(dāng)前窗口并保存圖片
im = Image.open(filename) # 打開圖片
im = im.crop((left, top, right, bottom)) # 截圖驗(yàn)證碼
im.save(filename) # 保存驗(yàn)證碼圖片
# 由于我處理的驗(yàn)證碼圖片沒有填多的線條,所以直接采用灰度是驗(yàn)證碼數(shù)字更加清晰,具體的處理方式可根據(jù)驗(yàn)證碼的實(shí)際情況而定
im = Image.open(filename)
# 轉(zhuǎn)換為灰度圖像
im = im.convert('L')
im.save(filename)
# 讀取圖片,應(yīng)為百度API中提供的方法參數(shù)只能是字節(jié)流
with open(filename, 'rb')as f:
image = f.read()
# 使用API中提供的方法識別驗(yàn)證碼并返回驗(yàn)證碼
data = client.basicGeneral(image)
try:
code = data['words_result'][0]['words']
except:
return data['error_msg']
driver.find_element_by_id('code').send_keys(code) # 輸入驗(yàn)證碼
driver.find_element_by_id('denglu').click() # 點(diǎn)擊登錄
time.sleep(1000) # 為了看清登錄,等待1000秒
if __name__ == '__main__':
print(scrapy(username, password)) # 傳入你在古詩文網(wǎng)注冊的賬號密碼
requests源碼
# -* coding: utf-8 *-
import os
import random
import re
import requests
from PIL import Image
from aip import AipOcr
from scrapy import Selector
headers = {
'referer': 'https://so.gushiwen.cn/user/login.aspx',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'
}
# 百度API參數(shù)
APP_ID = '23647800'
API_KEY = 'n95KOQgVuOMoAP72qZZo7uoN'
SECRET_KEY = '7yhyGglHUsY52DD8kf4w0Qjnxum07hMK'
def scrapy(username, password):
"""
:param username: 用戶名
:param password: 密碼
"""
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) # 調(diào)用API接口
conn = requests.Session() # 創(chuàng)建會話
resp = conn.get('https://so.gushiwen.cn/user/login.aspx', headers=headers) # 獲取登錄頁面
selector = Selector(text=resp.text)
__VIEWSTATE = selector.xpath('.//input[@id="__VIEWSTATE"]/@value').get()
__VIEWSTATEGENERATOR = selector.xpath('.//input[@id="__VIEWSTATEGENERATOR"]/@value').get()
img_url = 'https://so.gushiwen.cn/' + selector.xpath('.//img[@id="imgCode"]/@src').get() # 獲取圖片的路由
img = conn.get(img_url, headers=headers) # 獲取圖片路由
# 保存圖片
filename = str(random.random()) + '.png' # 隨機(jī)生成文件名, 圖片格式不能為jpg,API不支持jpg格式的識別
with open(filename, 'wb')as f:
f.write(img.content)
# 由于我處理的驗(yàn)證碼圖片沒有填多的線條,所以直接采用灰度是驗(yàn)證碼數(shù)字更加清晰,具體的處理方式可根據(jù)驗(yàn)證碼的實(shí)際情況而定
im = Image.open(filename)
# 轉(zhuǎn)換為灰度圖像
im = im.convert('L')
im.save(filename)
# 使用二進(jìn)制方式讀取圖片
with open(filename, 'rb')as f:
image = f.read()
# # 標(biāo)準(zhǔn)識別, 每天免費(fèi)50000次
# data = client.basicGeneral(image)
# 精確識別,每天免費(fèi)500次
data = client.handwriting(image)
# 捕獲一下接口識別當(dāng)中的錯(cuò)誤,可參照文檔查看報(bào)錯(cuò)原因
try:
code = data['words_result'][0]['words']
except:
return data['error_msg']
form_data = {
'__VIEWSTATE': __VIEWSTATE,
'__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR,
'from': '',
'email': username,
'pwd': password,
'code':cod,
'denglu': '登錄'
}
# 登錄
html = conn.post('https://so.gushiwen.cn/user/login.aspx', headers=headers, data=form_data).text
# 獲取登錄標(biāo)志位
login_flag = re.findall("alert\('(.*?)'\);",html)[0] if re.findall("alert\('(.*?)'\);",html) else ''
if not login_flag:
return '登錄成功!'
elif '驗(yàn)證碼有誤!' in login_flag:
return "驗(yàn)證碼錯(cuò)誤"
if __name__ == '__main__':
print(scrapy(username, password))
以上就是python爬蟲如何解決圖片驗(yàn)證碼的詳細(xì)內(nèi)容,更多關(guān)于python 解決圖片驗(yàn)證碼的資料請關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- 用Python爬蟲破解滑動驗(yàn)證碼的案例解析
- python網(wǎng)絡(luò)爬蟲實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼的方法
- Python爬蟲爬取ts碎片視頻+驗(yàn)證碼登錄功能
- Python爬蟲模擬登陸嗶哩嗶哩(bilibili)并突破點(diǎn)選驗(yàn)證碼功能
- Python3爬蟲里關(guān)于識別微博宮格驗(yàn)證碼的知識點(diǎn)詳解
- Python3爬蟲關(guān)于識別點(diǎn)觸點(diǎn)選驗(yàn)證碼的實(shí)例講解
- Python3爬蟲關(guān)于識別檢驗(yàn)滑動驗(yàn)證碼的實(shí)例
- Python3爬蟲中識別圖形驗(yàn)證碼的實(shí)例講解
- Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)之極驗(yàn)滑動驗(yàn)證碼的識別
- python爬蟲解決驗(yàn)證碼的思路及示例
- Python爬蟲實(shí)現(xiàn)驗(yàn)證碼登錄代碼實(shí)例
- python爬蟲之驗(yàn)證碼篇3-滑動驗(yàn)證碼識別技術(shù)
- python爬蟲之自動登錄與驗(yàn)證碼識別
- Python爬蟲爬驗(yàn)證碼實(shí)現(xiàn)功能詳解
- Python爬蟲模擬登錄帶驗(yàn)證碼網(wǎng)站
- 爬蟲Python驗(yàn)證碼識別入門