测试环境

  1. windows7+
  2. firefox50+
  3. geckodriver # firefox浏览器驱动
  4. python3
  5. selenium3

selenium UI自动化解决验证码的4种方法:去掉验证码、设置万能码、验证码识别技术-tesseract、添加cookie登录,本次主要讲解验证码识别技术-tesseract和添加cookie登录。

1. 去掉验证码

去掉验证码,直接通过用户名和密码登陆网站。

2. 设置万能码

设置万能码,就是不管什么情况,输入万能码,都可以成功登录网站。

3. 验证码识别技术-tesseract

准备条件

  1. tesseract,下载地址:https://github.com/parrot-office/tesseract/releases/tag/3.5.1
  2. Python3.x,下载地址:https://www.python.org/downloads/
  3. pillow(Python3图像处理库)

安装好Python,通过pip install pillow安装pillow库。然后将tesseract中的tesseract.exe和testdata文件夹放到测试脚本所在目录下,testdata中默认有eng.traineddata和osd.traineddata,如果要识别汉语,请自行下载对应包。

以下是两个主要文件,TesseractPy3.py是通过python代码去调用tesseract以达到识别验证码的效果。code.py是通过selenium获取验证码图片,进而使用TesseractPy3中的函数得到验证码,实现网站的自动化登陆。

TesseractPy3.py

#coding=utf-8import osimport subprocessimport tracebackimport loggingfrom PIL import Image # 来源于Pillow库TESSERACT = 'tesseract' # 调用的本地命令名称TEMP_IMAGE_NAME = "temp.bmp" # 转换后的临时文件TEMP_RESULT_NAME = "temp" # 保存识别文字临时文件CLEANUP_TEMP_FLAG = True # 清理临时文件的标识INCOMPATIBLE = True # 兼容性标识def image_to_scratch(image, TEMP_IMAGE_NAME):# 将图片处理为兼容格式image.save(TEMP_IMAGE_NAME, dpi=(200,200))def retrieve_text(TEMP_RESULT_NAME):# 读取识别内容inf = open(TEMP_RESULT_NAME + '.txt','r')text = inf.read()inf.close()return textdef perform_cleanup(TEMP_IMAGE_NAME, TEMP_RESULT_NAME):# 清理临时文件for name in (TEMP_IMAGE_NAME, TEMP_RESULT_NAME + '.txt', "tesseract.log"):try:os.remove(name)except OSError:passdef call_tesseract(image, result, lang):# 调用tesseract.exe,将识读结果写入output_filename中args = [TESSERACT, image, result, '-l', lang]proc = subprocess.Popen(args)retcode = proc.communicate()def image_to_string(image, lang, cleanup = CLEANUP_TEMP_FLAG, incompatible = INCOMPATIBLE):# 假如图片是不兼容的格式并且incompatible = True,先转换图片为兼容格式(本程序将图片转换为.bmp格式),然后获取识读结果;如果cleanup=True,操作之后删除临时文件。logging.basicConfig(filename='tesseract.log')try:try:call_tesseract(image, TEMP_RESULT_NAME, lang)text = retrieve_text(TEMP_RESULT_NAME)except Exception:if incompatible:image = Image.open(image)image_to_scratch(image, TEMP_IMAGE_NAME)call_tesseract(TEMP_IMAGE_NAME, TEMP_RESULT_NAME, lang)text = retrieve_text(TEMP_RESULT_NAME)else:raisereturn textexcept:s=traceback.format_exc()logging.error(s)finally:if cleanup:perform_cleanup(TEMP_IMAGE_NAME, TEMP_RESULT_NAME)

?code.py

#coding=utf-8from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support.ui import Selectfrom selenium.common.exceptions import NoSuchElementExceptionfrom selenium.common.exceptions import NoAlertPresentExceptionfrom PIL import Imageimport unittest, time, refrom TesseractPy3 import *class lgoin(unittest.TestCase):def setUp(self):self.driver = webdriver.Ie()self.driver.implicitly_wait(30)self.base_url = 'http://127.0.0.1:8080/test' # 要测试的链接self.title = '某管理平台' # 测试网站的Titleself.verificationErrors = []self.accept_next_alert = Truedef test_lgoin(self):driver = self.driverdriver.get(self.base_url)driver.maximize_window()driver.save_screenshot('All.png') # 截取当前网页,该网页有我们需要的验证码imgelement = driver.find_element_by_class_name('kaptchaImage')location = imgelement.location # 获取验证码x,y轴坐标size = imgelement.size # 获取验证码的长宽rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])) # 写成我们需要截取的位置坐标i = Image.open("All.png") # 打开截图result = i.crop(rangle) # 使用Image的crop函数,从截图中再次截取我们需要的区域result.save('result.jpg')text = image_to_string('result.jpg', 'eng').strip()assert self.title in driver.titledriver.find_element_by_id(u'userCode').clear()driver.find_element_by_id(u'userCode').send_keys('XXXXXX') # 用户名driver.find_element_by_id(u'password').clear()driver.find_element_by_id(u'password').send_keys('XXXXXX') # 密码#driver.find_element_by_name('verifyCode').clear()driver.find_element_by_name('verifyCode').send_keys(text)driver.find_element_by_name('submit').submit()def is_element_present(self, how, what):try: self.driver.find_element(by=how, value=what)except NoSuchElementException as e: return Falsereturn Truedef is_alert_present(self):try: self.driver.switch_to_alert()except NoAlertPresentException as e: return Falsereturn Truedef close_alert_and_get_its_text(self):try:alert = self.driver.switch_to_alert()alert_text = alert.textif self.accept_next_alert:alert.accept()else:alert.dismiss()return alert_textfinally: self.accept_next_alert = Truedef tearDown(self):#self.driver.quit()self.assertEqual([], self.verificationErrors)if __name__ == "__main__":unittest.main()

注意:最后,执行命令python code.py,就可以成功自动登录网站。

由于受验证码图片质量以及清晰度的影响,并不是每一次都能成功登陆。

4. 添加cookie登录

首先获取网站登陆后的cookie,然后通过添加cookie的方式,实现网站登陆的目的。我们用cook来表示xxxxxx的登录后的cookie。

# coding=utf-8from selenium import webdriver
import timedriver = webdriver.Firefox()
driver.get("http://www.xxxxxx.com/") # 要登陆的网站driver.add_cookie(cook) # 这里添加cookie,有时cookie可能会有多条,需要添加多次
time.sleep(3)# 刷新下页面就可以看到登陆成功了
driver.refresh()

登录时有勾选下次自动登录的请勾选,浏览器提示是否保存用户密码时请选择确定,这样获取的cookie成功登陆的机率比较高注意:

PYTHON+SELENIUM实现自动验证滑动验证码功能

总结一下:
1.使用selenium实现输入账号密码并点击登录。
2.使用urllib获取验证码的图片。
3.使用opencv来确定缺口的位置。
4.使用selenium实现拖动滑块到指定位置。

# pip install opencv-python
# pip install numpy
# pip install seleniumfrom selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
from urllib import request
import cv2
import numpy as np# 这个函数是用来显示图片的。
def show(name):cv2.imshow('Show', name)cv2.waitKey(0)cv2.destroyAllWindows()# 这里我用的google的驱动。
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(5)
url = 'https://juejin.im/'#实现登录
def get_login(driver, url):driver.get(url)driver.find_element_by_xpath('//button[@class="login-button"]').click()driver.find_element_by_xpath('//span[@class ="clickable"]').click()driver.find_element_by_xpath('//input[@name="loginPhoneOrEmail"]').send_keys('填入自己的账号')driver.find_element_by_xpath('//input[@name="loginPassword"]').send_keys('填入自己的密码')driver.find_element_by_xpath('//button[@class="btn"]').click()sleep(2)return driverdriver = get_login(driver, url)# 块图片
blockJpg = 'image/block.jpg'
# 模板图片
templateJpg = 'image/template.jpg'# 获取验证码中的图片
def get_image(driver):# 获取背景图urlbj = driver.find_element_by_xpath('//img[@class="sc-gZMcBi YkDbM sc-ifAKCX hCcViW"]').get_attribute('src')# 获取移动块urlyd = driver.find_element_by_xpath('//img[@class="captcha_verify_img_slide react-draggable sc-gqjmRU irZaUl"]').get_attribute('src')req = request.Request(bj)bg = open(templateJpg, 'wb+')bg.write(request.urlopen(req).read())bg.close()req = request.Request(yd)bk = open(blockJpg, 'wb+')bk.write(request.urlopen(req).read())bk.close()return templateJpg, blockJpgbkg, blk = get_image(driver)# 计算缺口的位置,由于缺口位置查找偶尔会出现找不准的现象,这里进行判断,如果查找的缺口位置x坐标小于100,
# 我们进行刷新验证码操作,重新计算缺口位置,知道满足条件位置。
def get_distance(bkg, blk):# 读取灰度图block = cv2.imread(blk, 0)tp = cv2.imread(bkg, 0)# 保存图像cv2.imwrite(templateJpg, tp)cv2.imwrite(blockJpg, block)block = cv2.imread(blockJpg)block = cv2.cvtColor(block, cv2.COLOR_BGR2GRAY)block = abs(255 - block)cv2.imwrite(blockJpg, block)block = cv2.imread(blockJpg)tp = cv2.imread(templateJpg)''' 模板匹配函数 cv2.matchTemplate(image, temp, method, result=None, mask=None)image:待搜索图像;temp:模板图像;result:匹配结果;method:计算匹配程度的方法'''result = cv2.matchTemplate(block, tp, cv2.TM_CCOEFF_NORMED)x, y = np.unravel_index(result.argmax(), result.shape)# x, y, w, h = cv2.boundingRect(GrayImage)# 这里就是下图中的绿色框框  50*50是移动块的大小cv2.rectangle(tp, (y, x), (y + 52, x + 52), (7, 249, 151), 2)print('x坐标为:%d' % x)print('y坐标为:%d' % y)if y < 80:elem = driver.find_element_by_xpath('//a[@class="secsdk_captcha_refresh refresh-button___StyledA-sc-18f114n-0 jgMJRc"]')sleep(1)elem.click()bkg, blk = get_image(driver)y, tp = get_distance(bkg, blk)return y, tpdistance, temp = get_distance(bkg, blk)# 这个是用来模拟人为拖动滑块行为,快到缺口位置时,减缓拖动的速度,服务器就是根据这个来判断是否是人为登录的。
def get_tracks(dis):v = 0m = 0.3# 保存0.3内的位移tracks = []current = 0mid = distance*4/5while current <= dis:if current < mid:a = 2else:a = -3v0 = vs = v0*m+0.5*a*(m**2)current += stracks.append(round(s))v = v0+a*mreturn tracks# 原图的像素是276*172,而网页的是340*212,图像放大了。  340/276 = 1.231884058
double_distance = int(distance*1.231884058)
tracks = get_tracks(double_distance)
# 由于计算机计算的误差,导致模拟人类行为时,会出现分布移动总和大于真实距离,这里就把这个差添加到tracks中,也就是最后进行一步左移。
tracks.append(-(sum(tracks)-double_distance))element = driver.find_element_by_xpath('//div[@class="secsdk-captcha-drag-icon sc-ckVGcZ gZcwqQ"]')
ActionChains(driver).click_and_hold(on_element=element).perform()
for track in tracks:ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()
sleep(0.5)
ActionChains(driver).release(on_element=element).perform()
show(temp)

python selenium UI自动化解决验证码的4种方法相关推荐

  1. Python+Selenium UI自动化 - alert/confirm/prompt窗口处理方法

    WebDriver中处理原生JS的alert.confirm以及prompt非常方便,三种弹出窗口均无法直接通过页面元素定位,不关闭窗口无法在页面上做其他操作 语法:         text:返回a ...

  2. Python Selenium UI自动化:滚动条滑动

    文章目录 问题 滑动至固定位置 Window 对象方法 - scrollTo js&python:滑动至固定位置 滑动至元素 元素对象方法 js&python:滑动至元素 问题 在UI ...

  3. Python Selenium UI自动化 ⽂件上传

      UI自动化进行文件上传,其实本质就是将所需上传的文件路径,传递给后端服务即可,至于读取文件的过程,其实开发人员已经在后端服务中完成了.所以我们要做的就是:拿到文件路径 -> 传出去.那么这里 ...

  4. Python+Selenium UI自动化 - 调用JS代码

    当webdriver遇到无法完成的操作时候,这个时候可以使用javascript来完成,webdriver提供了execute_script()接口来调用js代码. 执行js有两种场景: 1.在页面上 ...

  5. Python+Selenium UI自动化 - cookie处理方法及适用场景

    方法一:手动登录系统后,F12查看页面cookies的值,键值对的形式写入代码中 add_cookie方法,实际编写时,遇到某些参数无效的报错 可以直接把对应的键值对删除,举例仅写了一行数据,实际运行 ...

  6. Python Selenium UI 实现视频自动化播放

    Python Selenium UI 实现视频自动化播放 1.需求:实现某一课程自动播放 from selenium import webdriver from selenium.webdriver. ...

  7. 已解决python selenium模块自动化操作谷歌浏览器点击元素失效问题解决(亲测有效)

    已解决python selenium模块自动化操作浏览器点击元素,抛出异常selenium.common.exceptions.ElementClickInterceptedException: Me ...

  8. Python+Selenium 网页自动化 exe 程序编程实现(最全避坑指南)

    前言 在我的日常工作中,经常需要在内网(不连接互联网)的网页版办公系统中进行抓取网页数据.修改表单等大量重复性的操作.我就想是否可以编写出自动化的工具,将这些日常琐碎的操作变得轻松而高效.虽然本人非计 ...

  9. python+selenium实现自动化连接校园网

    python+selenium实现自动化连接校园网(资源下载链接在总结) 校园网的自动连接 在学校里面,我经常会用到校园WiFi.我个人使用的是办移动套餐送的wifi套餐,因此,我连接的WiFi是NJ ...

最新文章

  1. linq to sql初步
  2. 这些动物,你认识几个呢
  3. 皮一皮:追忆我那随风逝去的阔腿裤...
  4. 使用Injection Token将字符串类型的参数注入到类的构造函数里
  5. caffe 下测试 MNIST数据
  6. DBA用于查询当前数据库表格记录条数的脚本
  7. 学习MySQL / MariaDB初学者 - 第1部分
  8. java中ant是干什么的_java_ant详解
  9. ipc.Client: Retrying connect to server: h1/192.168.1.61:9000. Already tried 0 time(s);解决方法
  10. 数据结构题集(c语言版)严蔚敏答案pdf
  11. 计算机基础高一知识点,计算机基础全部知识点_.doc
  12. PHP判断是手机端访问还是PC端访问网站
  13. Knowledge Distillation via Route Constrained Optimization
  14. 图文讲解:Win8必知快捷键汇总_-Chaz-_新浪博客
  15. 天下数据解析域名及域名转向
  16. XCode json数据处理、通过图片URL获取UIImage、通过URL显示网页
  17. 英语口语8000句-随意的谈话
  18. 计算机基础:调整显示器分辨率及刷新率
  19. 谈瓦克生产基地爆炸停产对中国多晶硅市场的影响
  20. 2016年8月13日 星期六 --出埃及记 Exodus 16:14

热门文章

  1. MQTT开源库mosquitto安装和使用(一)
  2. 数学建模基础算法Chapter2.1 -- 整数规划(ILP): 分支定界+割平面
  3. HCIP之BGP的选路原则
  4. 降噪耳机哪个牌子好?商务用蓝牙降噪耳机推荐
  5. 全方位掌握 NSIS 的操作
  6. 配上新的pip源再来安装pytorch有如神助
  7. Shading中的插值技术
  8. 专题论坛:云计算安全论坛
  9. 【Java】如何编写、运行一个Java程序
  10. 信号检测与估计理论_论文解读 | 利用脑功能连接实现疲劳驾驶检测