草庐IT

selenium--验证码识别,一文教会你回答面试官

奔跑的托马 2023-04-21 原文

相信大家在日常划水,培训,工作中都遇到这样的问题,验证码怎么处理?也有一些面试官会这么问。

这里大致的说说,最常见的处理方式。

1、万能验证码:所谓的万能验证码也就是找开发固定一个验证码,比如abcd,12cd这种,每次打开固定不变,永远都是同一个验证码。或者说是,不管你输入什么验证码都是正确的,代码不对验证码进行校验。

2、注销验证码:这里呢就是直接找开发,经过协商,开发把验证码这一块代码注释掉。这里跟上述所说的其实类似。

3、cookie登录:了解过接口的都知道,登录账号密码过程中,其实是一次发起请求的过程,有发起请求对应的会有返回响应。那么cookie就在这里面了。我们可以通过循环里面的内容,绕过登录这个环节,直接进入登录后的界面。后续会出文。

4、最后一种,那当然就是本篇要介绍的,纯技术搞定。图像识别。本文介绍两种。第一种pytesseract+PIL,第二种就是一个库,我也是最近才发现的:ddddocr。我理解的就是懂得都懂orc。玩笑开完,先来简单看看例子。

pytesseract+PIL

这种需要用到工具Tesseract-OCR,下载地址:https://digi.bib.uni-mannheim.de/tesseract/

还需要配置环境变量:

第一,在系统变量path中添加:E:\picture_dev\Tesseract-OCR,这里是你安装的路径,需要根据自己的实际安装路径更改。

第二:系统变量path新建一个环境,并且将你下载解压的Tesseract-OCR路径写进去,如下图

这两下载完了,接下来就是:

pip install Pillow

pip install pytesseract

下载工具对应所需要的包啦。下载完后试试如下两个命令:

接下来我们可以开始写代码了:

# -->>>托马<<<---

from PIL import Image

import pytesseract

# 打开图片

image = Image.open(r'PIC/3.jpg')

# 灰度处理

image1 = image.convert('L')

# 识别图片,lang是对应的字体

text = pytesseract.image_to_string(image,lang='eng')

# 打印识别内容

print(text)

好了,这里是个简单的例子。验证码可以自己百度上找。打开图片这里的路径根据自己的实际情况更改。lang='eng'这里,也可以不要,这里的意思就是识别中文还是英文,如果是中文那么需要另外下来语言包。默认英文。

这里,有很多朋友跑起来之后会报错,提示你什么什么path没有发现或者不对的。改一下配置就好。上述代码中按住ctrl鼠标点击image_to_string方法,会进入到pytesseract.py文件,一直上滑或者CTRL+F搜索关键字。

将此处注释的改成你的Tesseract-OCR文件内的tesseract.exe路径即可,然后重启电脑

注意:这样的方法可以识别验证码码,但是准确率太低了,甚至有很多不能识别。所以介绍到此结束。

ddddocr

这个包就比上一个方法强很多了。识别率也是比较不错的。但是呢,作者比较的流氓。大佬很强但是也很流氓。至于为什么这么说,各位去试试就知道了。

pip install ddddocr

好了玩笑到这里。大家不喜欢作者的库每次打开后都有一些介绍信息的可以去源代码删了,下面会介绍。

from ddddocr import DdddOcr

# 实例化方法

ocr = DdddOcr()

# 打开图片

file = open(r'./PIC/7.png','rb')

# 读取图片

img = file.read()

# 识别图片

result = ocr.classification(img)

# 打印内容

print(result)

上述例子,验证码自己备好哦。上述简单的例子就能完成验证码图片识别了。可以自己去试试。

DdddOcr是里面的一个类方法。里面还有一些其他的功能各位大佬自己去试试吧。本文只介绍图片识别哦。上面比较的好理解吧。那么我们进入实战。

"""

体验管理员: admin

密码: shopxo

https://d2.shopxo.vip/admin.php?s=admin/logininfo.html

"""

是一个后台管理的地址,请不要乱删改里面的内容,作者开源不易。

我们先用最简单的脚本来写一下:

# -->>>托马<<<---

from PIL import Image

from ddddocr import DdddOcr

from selenium import webdriver

from time import sleep

"""

体验管理员: admin

密码: shopxo

https://d2.shopxo.vip/admin.php?s=admin/logininfo.html

"""

fox = webdriver.Firefox()

fox.get('https://d2.shopxo.vip/admin.php?s=admin/logininfo.html')

fox.find_element_by_xpath("//input[@name='accounts']").send_keys('admin')

fox.find_element_by_xpath("//input[@name='pwd']").send_keys('shopxo')

pic = fox.find_elements_by_xpath("//span[@class='am-input-group-btn']")[1]

sleep(2)

# 保存截图

fox.save_screenshot('./PIC/6.png')

# 获取位置

location = pic.location

print(location)

# 获取大小

pic_size = pic.size

print(pic_size)

# 确定所需要的图片大小

rangle = (int(location['x']-5), int(location['y']-5), int(location['x'] + pic_size['width']+11),

int(location['y'] + pic_size['height']+7))

# 打开之前截图图片

image = Image.open('./PIC/6.png')

# 开始裁剪

image1 = image.crop(rangle)

# 保存裁剪后的截图

image1.save('./PIC/7.png')

# 实例化类方法

ocr = DdddOcr()

# 打开图片,二进制形式

file = open(r'./PIC/7.png','rb')

# 读取图片

img = file.read()

# 识别图片验证码

result = ocr.classification(img)

print(result)

fox.find_element_by_xpath("//input[@name='verify']").send_keys(result)

fox.find_element_by_xpath("//*[text()='登录']").click()

很多人看了这里是不是麻了,哈哈哈,我自己写的也看麻了。后续会优化在框架中体现。亦或者出一篇优化的文。

基础脚本麻,我们简单说说其中重要的,selenium基础就不用多说了。最主要的是截图验证码那部分,也就是代码中的rangle变量。这里需要根据实际情况进行调整,把整个验证码框截取下来,也就是在原来的坐标上,进行加减乘除。

代码中有x+y的一部分代码,这里是为什么呢,是我们获取到的一个验证码是根据坐标轴来的,也就是说,这里的x+y实则取得是长宽的一个范围。我想截取一个长方形,我需要知道长跟宽吧。那么如何知道了,那就是此处的取值了。就好歹我从左下角开始取值,我想得到一个验证码这样长方形的图,那么终点只能是右上角。

注意:这里验证码识别只是举例了,实际情况还是需要根据项目来才行, 毕竟这个库识别率虽然OK,但是难免也会有出错的时候。所以,在用技术自动登录的过程中,还需要做很多的判断来避免错误让它自己登录自己判断的更流畅。

有关selenium--验证码识别,一文教会你回答面试官的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. ruby-on-rails - 如何将验证与模型分开 - 2

    我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

  6. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  7. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  8. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  9. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  10. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

随机推荐