lsekfe 发表于 2020-8-3 11:18:09

Selenium+Tesseract破解登录验证码

前言  我破解的登录验证码类型是数学公式的这种,即http://www.51testing.com/attachments/2020/06/15243603_202006291343521Kvmj.jpg
  .......是不是看起来比较简单,但是Tesseract对这种图片的识别率也很低,后期要提升识别率的话,我觉得一是要对图片进行降噪和锐化等处理,二是要对Tesseract预先训练,训练的工具我推荐jTessBoxEditor,大家有兴趣的可以了解一下。
  1 安装Tesseract
  1.1 下载Tesseract。地址为:Windows Installer made with MinGW-w64,下载完直接安装即可,安装完成后配置一下环境变量。编辑一下系统变量里的path,添加如下环境变量。
C:\Program Files(x86)\Tesseract-OCR安装完成后,在cmd命令行窗口输入
tesseract -v
 出现如下内容证明安装成功。

1.2 安装pytesseract
pip install pytesseract2 识别代码  2.1 识别逻辑。首先使用selenium到浏览器找到验证码标签,然后截图保存下来,再用tesseract去识别这张图片。如果识别失败,再用selenium点击一下验证码图片,重新生成一张验证码,再重复之前的识别逻辑。如果识别成功,使用eval计算出算式的数值,填入后点击登录按钮。
  2.2 代码
import time

  import pytesseract

  from selenium.webdriver import Chrome

  from PIL import Image

  driver = Chrome(executable_path=r'D:\Chrome Downloads\chromedriver.exe')# chromedriver的存放路径

  url = "http://60.210.111.130:8002/Login.aspx"

  print("开始爬取,url为{}".format(url))

  driver.get(url=url)

  time.sleep(2)

  # 找到username的input标签,填入用户名

  username = driver.find_element_by_id('txtUserName')

  username.clear()

  username.send_keys('your username')

  # 找到password的input标签,填入密码。如果再次点击验证码时密码被清空,那么这段代码要放到while循环内部

  password = driver.find_element_by_id('pwd')

  password.clear()

  password.send_keys('your password')

  # 进行20次尝试

  times = 0

  while True:

  try:

  element = driver.find_element_by_id('validimg')

  element.click()

  # 每次请求的验证码图片都不一样,所以只能截图,保存至本地。

  driver.save_screenshot('validImage.png')

  # windows系统要注意页面缩放比例,如果是150%,那么每项都*1.5。linux系统不需要

  left = element.location['x']*1.5

  top = element.location['y']*1.5

  right = element.location['x']*1.5 + element.size['width']*1.5

  bottom = element.location['y']*1.5 + element.size['height']*1.5

  im = Image.open('validImage.png')

  im = im.crop((left, top, right, bottom))# 抠图

  im.save('validImage.png')

  data = pytesseract.image_to_string(Image.open('validImage.png'))

  if len(data) < 3:# 未识别

  continue

  if len(data) == 4:# 识别的带=号,去掉=号

  data = data[:3]

  if data == ".":# -号经常别识别成.,替换为-号

  data = "-"

  print("ocr识别结果", data)

  valid_code = driver.find_element_by_id('validcode')

  valid_code.clear()

  valid_code.send_keys(eval(data))

  time.sleep(1)

  btnLogin = driver.find_element_by_id('btnLogin')

  btnLogin.click()

  # 获取cookie

  login_cookie = driver.get_cookie('ASP.NET_SessionId')

  total_cookie = 'ASP.NET_SessionId={}; autoLogin=null; user=null; pwd=null'.format(login_cookie['value'])

  print("total_cookie,{}".format(total_cookie))

  break

  except Exception as e:

  time.sleep(2)

  times += 1

  print("破解验证码失败,重试第{}次".format(times))

  if times == 20:

  raise RuntimeError

  # linux系统要注意退出chromedriver。否则如果多次执行的话,会生成大量的chromedriver进程。

  driver.quit()执行结果如下:


其中比较坑的一点就是,windows系统显示有缩放比例。可以在桌面右键-显示设置-缩放与布局中看到。如果缩放比例是150%的话,那么截图部分,每项参数都要*1.5,否则截不到想要的验证码。



violet_mary 发表于 2020-9-5 22:32:58

谢谢

Miss_love 发表于 2020-12-25 11:01:08

学习
页: [1]
查看完整版本: Selenium+Tesseract破解登录验证码