发布时间:2018-08-21 16:49:52编辑:Run阅读(11154)
利用Selenium模拟登陆解决验证码的问题
验证码解决方案有很多种:
1 通过第三方的打码平台,识别率高...一般都是收费的,价格还不便宜
2 自己通过切图,再结合图片识别的库,去识别验证码... 简单的验证码识别率还可以,但是复杂的验证码需要训练(机器学习), 难度大
3 通过手动登陆,获取cookie信息,利用cookie实现免登陆... cookie一般都是有 有效期的,时间一过,那么下次就又需要手 动登陆去获取新的cookie,很繁琐,实现简单
4 利用切图把验证码图片切出来,再通过手动输入验证码去登陆(账号,密码可让程序自行输入)...每次登陆都需要手动输入 验证码登陆,很繁琐,实现简单
本次环境,将使用第四种方法来解决验证码问题
目标网站:https://www.baidu.com 模拟登陆百度
在模拟登陆百度之前,首先手动输错几次,让验证码显示出来
默认登陆是不需要验证码的,但输错2次之后,就需要验证码了,如下图:
PS:运行次脚本前,先模拟登陆失败几次,不然验证码不会出来
Selenium登陆百度代码如下:
class LoginBaiDu(object): def __init__(self, url, password, username): self.url = url self.password = password self.username = username self.browser = self.getbrowser() self.run(self.browser) def getbrowser(self): chrome_options = webdriver.ChromeOptions() browser = webdriver.Chrome(options=chrome_options, executable_path=r'D:\chromedriver_2.41\chromedriver.exe') browser.get(self.url) # 清除cookies记录 browser.delete_all_cookies() return browser def run(self, browser): # 找到登陆按钮 browser.find_element_by_xpath("//div[@id='u1']/a[text()='登录']").click() # 等待网站加载 browser.implicitly_wait(3) # 定位弹出框 browser.current_window_handle # 找到用户名登录按钮,并点击登录 browser.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn').click() time.sleep(2) # 找到输入用户名的input标签,模拟输入用户名 browser.find_element_by_id("TANGRAM__PSP_10__userName").send_keys(self.username) time.sleep(3) # 找到输入密码的input标签,模拟输入密码 browser.find_element_by_id("TANGRAM__PSP_10__password").send_keys(self.password) time.sleep(10) # 对整个页面进行截图 browser.get_screenshot_as_file('login.png') # 定位验证码的坐标 code = browser.find_element_by_xpath("//span[@class='pass-verifyCodeImgParent']\ /img[@id='TANGRAM__PSP_10__verifyCodeImg']") # 计算验证码四个点的坐标 left = code.location['x'] top = code.location['y'] right = code.location['x'] + code.size['width'] bottom = code.location['y'] + code.size['height'] print("验证码坐标::", left, top, right, bottom) # 利用python的图像处理库,将验证码切出来,保存验证码code.png到当前目录 im = Image.open('login.png') im = im.crop((left, top, right, bottom)) im.save('code.png') self.user_input(browser) def user_input(self, browser): # 查看code.png图片,手动输入验证码 user_code = input("验证码:").strip() # 找到验证码的输入框,并将手动输入的验证码赋值到验证码输入框 browser.find_element_by_id("TANGRAM__PSP_10__verifyCode").send_keys(user_code) # 找到登陆按钮,并点击登录 browser.find_element_by_id("TANGRAM__PSP_10__submit").click() try: # 如果登陆成功,获取用户信息 username = browser.find_element_by_id("s_username_top").text if username: print('登陆成功') print(username) # 登陆失败,打印错误信息 except Exception as e: print("登陆失败错误信息:{}".format(e)) finally: # 退出程序 time.sleep(10) browser.quit() if __name__ == '__main__': url = 'https://www.baidu.com' username = '账号' password = '密码' st = LoginBaiDu(username=username, password=password, url=url)
运行程序截图
程序到了验证码那里,会停住,需要手动输入验证码
输入验证码后,会自动赋值到验证码的输入框
然后就可以看到显示登录成功,打印用户信息
还会在当前目录下,生成两个png图片
login.png截图
code.png为切出来的验证码
47616
46004
36920
34486
29096
25742
24578
19725
19265
17766
5581°
6167°
5703°
5757°
6718°
5496°
5501°
6001°
5975°
7306°