一、简介
初次开始使用Selenium,于是开始用登录作为联手项目,是一个真实的登录界面,包含验证码(验证码是难点,获取与识别),以下会讲的很详细,我怕我下次又忘记了
我采用Selenium + python + 百度云OCR,安装等教程自行百度,我就不多说了
二、selenium打开浏览器获取相应el
from selenium import webdriver
from selenium.webdriver.common.by import By
import base64
#注册Chrome驱动,打开浏览器网址
driver = webdriver.Chrome()
url = "************"
driver.get(url)
#获取相应el
driver.find_element(By.NAME,"***").send_keys('***')
driver.find_element(By.NAME, "***").send_keys('***')
#获取图片
png = driver.find_element(By.CSS_SELECTOR,"****")
img_url = png.get_attribute("src") # 获得图片的url,本次测试的是bs64生成,采用解码获得图片
head, context = img_url.split(",") # 截取后字段的bas64编码
img_data = base64.b64decode(context)
image = Image.open(BytesIO(img_data));
image.save("capt.png")
这段代码主要是利用selenium打开网站,获取到相应的dom,find_element_by_id等写法已经统一换为find_element(By.ID, “***”)等了,先将图片保存下来考研方便后续的识别
三、验证码预处理
验证码一般无法直接识别,我们需要通过灰度、二值、降噪等手段,使得图片更加清晰,提高图片的识别准确率
下列代码需要提前引入以下包
from PIL import Image
1.灰度化
img = img.convert('L') # P模式转换为L模式(灰度模式默认阈值127)
2.二值化
count = 230 # 设定阈值,阈值的大小由图片的清晰度等自行调节
table = []
for i in range(256):
if i < count:
table.append(0)
else:
table.append(1)
img = img.point(table, '1')
img.save('captcha.png')
3.降噪
pixdata = img.load()
w,h = img.size
for y in range(1,h-1):
for x in range(1,w-1):
count = 0
if pixdata[x,y-1] > 245:
count = count + 1
if pixdata[x,y+1] > 245:
count = count + 1
if pixdata[x-1,y] > 245:
count = count + 1
if pixdata[x+1,y] > 245:
count = count + 1
if count > 2:
pixdata[x,y] = 255
return img
四、百度云识别
需要提前注册
from aip import AipOcr
# 识别码
APP_ID = '****'
API_KEY = '****'
SECRET_KEY = '****'
# 初始化对象
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
# 读取图片
def get_file_content(file_path):
with open(file_path, 'rb') as f:
return f.read()
image = get_file_content('end.png') # 传入图片
# 定义参数变量
options = {'language_type': 'ENG', } # 识别语言类型,默认为'CHN_ENG'中英文混合
# 调用通用文字识别
result = client.basicGeneral(image, options) # 高精度接口 basicAccurate
for word in result['words_result']:
captcha = (word['words'])
print('识别结果:' + captcha)
return captcha
五、完整代码
import base64
from io import BytesIO
from selenium import webdriver
from selenium.webdriver.common.by import By
from PIL import Image
from time import sleep
from aip import AipOcr
# 对二值化的图像进行降噪处理,使得识别更加准确
def depoint(img):
pixdata = img.load()
w,h = img.size
for y in range(1,h-1):
for x in range(1,w-1):
count = 0
if pixdata[x,y-1] > 245:
count = count + 1
if pixdata[x,y+1] > 245:
count = count + 1
if pixdata[x-1,y] > 245:
count = count + 1
if pixdata[x+1,y] > 245:
count = count + 1
if count > 2:
pixdata[x,y] = 255
return img
# 获得验证码,并进行处理,二值化
def deal_image():
png = driver.find_element(By.CSS_SELECTOR,".*******")
img_url = png.get_attribute("src") # 获得图片的url,本次测试的是bs64生成,采用解码获得图片
head, context = img_url.split(",") # 截取后字段的bas64编码
img_data = base64.b64decode(context)
image = Image.open(BytesIO(img_data));
image.save("capt.png")
img = Image.open('capt.png')
img = img.convert('L') # P模式转换为L模式(灰度模式默认阈值127)
count = 230 # 设定阈值,阈值的大小由图片的清晰度等自行调节
table = []
for i in range(256):
if i < count:
table.append(0)
else:
table.append(1)
# print(table)
img = img.point(table, '1')
img.save('captcha.png')
# 调用百度云OCR API 进行识别
def discern_captcha():
# 识别码
APP_ID = '****'
API_KEY = '****'
SECRET_KEY = '****'
# 初始化对象
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
# 读取图片
def get_file_content(file_path):
with open(file_path, 'rb') as f:
return f.read()
image = get_file_content('end.png') # 传入图片
# 定义参数变量
options = {'language_type': 'ENG', } # 识别语言类型,默认为'CHN_ENG'中英文混合
# 调用通用文字识别
result = client.basicGeneral(image, options) # 高精度接口 basicAccurate
for word in result['words_result']:
captcha = (word['words'])
print('识别结果:' + captcha)
return captcha
# 登录事件,若识别不准确需点击第二次重复
def ClickRandomCode():
deal_image()
image = depoint(Image.open('captcha.png'))
image.save('end.png')
image = depoint(Image.open('end.png'))
image.save("end.png")
randomCode = discern_captcha()
driver.find_element(By.NAME, "randomCode").send_keys(randomCode)
driver.find_element(By.CSS_SELECTOR, ".card-z .el-button").click()
sleep(2) # 错误或成功信息有延迟
try:
text = driver.find_element(By.CSS_SELECTOR, ".el-message__content").text
if (text == "验证码错误"):
driver.find_element(By.CSS_SELECTOR, ".verification-code > img").click()
driver.find_element(By.CSS_SELECTOR, ".verification-code > img").clear()
ClickRandomCode() # 递归调用直至正确
print("验证码错误")
else:
print("登录成功")
except:
print("ok")
def login(***,***):
driver.find_element(By.NAME,"****").send_keys(***)
driver.find_element(By.NAME, "***").send_keys(***)
ClickRandomCode()
if __name__ == '__main__':
driver = webdriver.Chrome()
url = "*****"
driver.get(url)
login("****","****")