序言
在模拟网页的表单登陆的时候,比较头疼的一个问题就是图片验证码的情况,碰到了验证码,比如像普通的文字图片类型的验证码,目前一个比较好的思路就是,通过selenium自身提供的截图功能,对指定的图片验证码区域进行截图,然后进行识别,最后填充表单进行登陆
网上不少资料关于验证码识别登陆这一块,都没有一个比较完整的可参考的代码,下面说说我的具体解决思路和过程
代码思路
1、登陆网页截图并保存
2、找到图片验证码或者验证码所在的表单或者尽可能小的区域位置,并截取出来
3、利用超级鹰识别图片验证码并解析验证码
下面是具体的代码,以“去哪儿网”,去哪儿网登录页面有验证码
步骤一,从整个网页截图中再截取带有验证码的图片
#截取表单图片
def get_form_image():
save_pc_path = 'D:\\pic\\image\\form.png'
save_pc_crop_path = 'D:\\pic\\image\\crop.png'
url = 'http://user.qunar.com/passport/login.jsp?ret=https%3A%2F%2Fwww.qunar.com%2F%3Fex_track%3Dauto_4e0d874a'
driver = webdriver.Chrome(executable_path="D:/logs/python代码/driver/chromedriver.exe")
driver.get(url)
driver.implicitly_wait(10)
# 切换登录模式为账号密码登录
first_botton = driver.find_element_by_class_name('pwd-login')
first_botton.click()
# 首先截取整个屏幕的图片
driver.save_screenshot(save_pc_path)
#获取表单信息并截图
#element = driver.find_element_by_xpath("//form[@id='loginForm']")
element = driver.find_element_by_xpath("//div[@class='field-vercode clearfix']/p")
left = element.location['x']
top = element.location['y']
#645,178
print(left,top)
image_width = element.size['width']
image_height = element.size['width']
right = element.location['x'] + 320
bottom = element.location['y'] + 120
im = Image.open(save_pc_path)
im = im.crop((left, top, right, bottom))
im.save(save_pc_crop_path)
print("图片截取并保存成功")
步骤二、使用超级鹰识别图片验证码
#超级鹰识别验证码
def recognize_image():
account = '你的超级鹰账户'
password = '你的超级鹰密码'
id='902752'
image_kind=1902
chaojiying = Chaojiying_Client(account, password, id)
save_pc_crop_path = 'D:\\pic\\image\\crop.png'
im = open(save_pc_crop_path, 'rb').read()
image_num = chaojiying.PostPic(im, image_kind)
if image_num['err_str'] == 'OK':
print('验证码识别成功')
print('验证码是{0}'.format(image_num['pic_str']))
return image_num['pic_str']
else:
print('验证码识别失败')
步骤三,测试验证
if __name__ == '__main__':
get_form_image()
recognize_image()
我们看看保存成功的图片验证码,说明超级鹰还是很给力的
以上便是进行图片验证码识别的整个代码,代码并不复杂,主要是这样一个思路,下面就给出登陆去哪儿网的完整代码,提供参考,代码中,有一些变量可以进一步的优化和封装,使代码看起来更精致和优雅
扫描二维码关注公众号,回复:
9004875 查看本文章
import requests
from chat1.tools.chaojiying import Chaojiying_Client# 必须先把官方的Api文件放到同级目录下
from selenium import webdriver
import time
from PIL import Image
headers = {
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36',
}
#截图
#截取表单图片
def get_form_image(save_pc_path,driver):
#save_pc_path = 'D:\\pic\\image\\form.png'
save_pc_crop_path = 'D:\\pic\\image\\crop.png'
driver.implicitly_wait(10)
# 切换登录模式为账号密码登录
first_botton = driver.find_element_by_class_name('pwd-login')
first_botton.click()
# 首先截取整个屏幕的图片
driver.save_screenshot(save_pc_path)
#获取表单信息并截图
#element = driver.find_element_by_xpath("//form[@id='loginForm']")
element = driver.find_element_by_xpath("//div[@class='field-vercode clearfix']/p")
left = element.location['x']
top = element.location['y']
#645,178
print(left,top)
image_width = element.size['width']
image_height = element.size['width']
right = element.location['x'] + 320
bottom = element.location['y'] + 120
im = Image.open(save_pc_path)
im = im.crop((left, top, right, bottom))
im.save(save_pc_crop_path)
print("图片截取并保存成功")
return save_pc_crop_path
#获取图片验证码
def get_img_num(save_pc_path,driver):
driver.get_screenshot_as_png()
time.sleep(2)
account = '1382551'
password = 'congge'
id = '902752'
image_kind = 1902 # 四位英文或数字
#获取屏幕的表单截图
image_path = get_form_image(save_pc_path,driver)
chaojiying = Chaojiying_Client(account, password, id)
im = open(image_path, 'rb').read()
image_num = chaojiying.PostPic(im, image_kind)
if image_num['err_str'] == 'OK':
print('验证码识别成功')
print('验证码是{0}'.format(image_num['pic_str']))
return image_num['pic_str']
else:
print('验证码识别失败')
# 此处登录窗口没有在iframe框架里面,如果再iframe框架里面一定要先进入框架里面
def login():
# 记得先在主页点一次
url = 'http://user.qunar.com/passport/login.jsp?ret=https%3A%2F%2Fwww.qunar.com%2F%3Fex_track%3Dauto_4e0d874a'
driver = webdriver.Chrome(executable_path="D:/logs/python代码/driver/chromedriver.exe")
driver.get(url)
driver.implicitly_wait(10)
# 切换登录模式为账号密码登录
first_botton = driver.find_element_by_class_name('pwd-login')
first_botton.click()
#使用zha那个号登陆
driver.find_element_by_xpath("//label[@for='radio_normal'][1]").click()
#获取用户名
username = driver.find_element_by_xpath("//div[@class='field-login']/div/input[@name='username']")
username.clear()
username.send_keys('1382551')
time.sleep(3)
# 获取密码
password = driver.find_element_by_xpath("//input[@name='password']")
password.clear()
password.send_keys('congge')
time.sleep(2)
save_pc_path = 'D:\\pic\\image\\form.png'
driver.save_screenshot(save_pc_path)
#属于验证码
image_input = driver.find_element_by_xpath("//input[@name='vcode']")
image_input.clear()
image_num = get_img_num(save_pc_path,driver)
image_input.send_keys(image_num) # 输入验证码
time.sleep(2)
#点击登录按钮
login_button = driver.find_element_by_id('submit') # 点击登录按钮
login_button.click()
print("登陆成功")
if __name__ == '__main__':
login()
总结来说,要实现一个功能如果想通了可能并不复杂,甚至几行代码就可以搞定,重要的是这个思考的过程,以及寻找解决问题的思路,原来编程竟然是一门方法论啊,最后,感谢观看!