本文共 7823 字,大约阅读时间需要 26 分钟。
验证码是许多网站都采取的反爬虫机制,随着技术的发展,验证码出现了各种各样的形态。从一开始的几个数字,发展到随机添加几个英文字母以及混淆曲线、彩色斑点、滑动拼图等,形态越来越复杂。本篇博文将介绍如何使用 OCR 技术实现字符验证码的识别、如何使用第三方验证码识别平台识别验证码以及滑动拼图验证码的校验工作。
字符验证码的特点就是验证码中包含数字、字母或者掺杂着斑点与混淆曲线的图片验证码。识别此类验证码,首先需要找到验证码图片在网页 HTML 代码中的位置,然后将验证码下载,最后再通过 OCR 技术进行验证码的识别工作。
Tesseract-OCR 是一个免费、开源的 OCR 引擎,通过该引擎可以识别图片中的验证码,搭建 OCR 的具体步骤如下:
(1) 点击 打开 Tesseract-OCR下载地址,然后选择与自己操作系统匹配的版本(博主电脑为 Windows 64位操作系统),如下图所示。此电脑
依次选择属性 ⇒ 高级系统设置 ⇒ 环境变量,然后在上面的用户变量中单击 新建
,在弹出的 新建用户变量
窗口中设置变量名与变量值,如下图所示。 (4) 接下来需要安装 tesserocr 模块,安装命令如下:
pip install tesserocr # 读者可自行添加镜像加快下载速度如果使用的是 Anaconda 并在安装 tesserocr 模块时出现了错误,可以使用如下命令:conda install -c simonflueckiger tesserocr
如果以上两种安装 tesserocr 模块的方式都遇到问题时,可以从下面百度网盘中下载 tesserocr-2.4.0-cp37-cp37m-win_amd64.whl,接着启动 命令提示符窗口
,然后通过 pip install tesserocr-2.4.0-cp37-cp37m-win_amd64.whl
安装 tesserocr 模块。
链接:https://pan.baidu.com/s/1uE0BwOnGkxzzXjMqyKtCnA 提取码:i19b 复制这段内容后打开百度网盘手机App,操作更方便哦--来自百度网盘超级会员V6的分享
以下面地址对应的网页为例,下载网页中的验证码图片,具体步骤如下:
测试网页地址:https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx
(1)使用浏览器打开测试网页的地址,将显示下图所示的字符验证码。
# -*- coding: UTF-8 -*-"""@author:AmoXiang@file:1.download_pic.py@time:2021/01/19"""import requests # 导入网络请求模块import urllib.requestfrom bs4 import BeautifulSoup # 导入解析HTML的模块headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"}# 发送网络请求url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"response = requests.get(url=url, headers=headers)html = BeautifulSoup(response.text, "lxml")img_src = html.select("#imgCode")[0].attrs["src"] # 解析图片src# 组合验证码图片请求地址img_url = "https://so.gushiwen.cn/" + img_src# 下载并设置图片名称urllib.request.urlretrieve(img_url, "code.png")
程序运行后项目文件夹中将自动生成下图所示的验证码图片。
验证码下载完成以后,如果没有安装 pillow 模块,需要通过 pip install pillow
命令安装一下,然后导入 tesserocr 与 Image 模块,再通过 Image.open() 方法打开验证码图片,接着通过 tesserocr.image_to_text() 函数识别图片中的验证码信息即可。示例代码如下:
# -*- coding: UTF-8 -*-"""@author:AmoXiang@file:demo.py@time:2021/01/19"""import tesserocr # 导入tesserocr模块from PIL import Image # 导入图像处理模块img = Image.open("code.png") # 打开验证码图片code = tesserocr.image_to_text(img) # 将图片中的验证码转换为文本print(f"验证码为: {code}")
博主重新生成了一张验证码图片,程序运行结果如下:
import tesserocr # 导入tesserocr模块from PIL import Image # 导入图像处理模块img = Image.open("code.png") # 打开验证码图片code = tesserocr.image_to_text(img) # 将图片中的验证码转换为文本print(f"验证码为: {code}")
程序运行结果如下:
import tesserocrfrom PIL import Imageimg = Image.open("code.png")img = img.convert("L")t = 155table = []for i in range(256): if i < t: table.append(0) else: table.append(1)img = img.point(table, "1")img.show()code = tesserocr.image_to_text(img) # 将图片中的验证码转换为文本print(f"验证码为: {code}")
程序运行后将自动显示下图所示二值化处理后的验证码图片。
虽然 OCR 可以识别验证码图片中的验证码信息,但是识别效率与准确度不高是 OCR 的缺点。所以使用第三方验证码识别平台是一个不错的选择,不仅可以解决验证码识别效率低的问题,还可以提高验证码识别的准确度。使用第三方平台识别验证码是非常简单的,平台提供了完善的 API 接口,根据平台对应的开发文档即可完成快速开发的需求,但每次验证码成功识别后平台会收取少量的费用。
验证码识别平台一般分为两种,分别是打码平台和 AI 开发者平台。打码平台主要是由在线人员进行验证码的识别工作,然后在较短的时间内返回结果。AI 开发者平台主要是由人工智能来进行识别,例如,百度 AI。
下面以打码平台为例,演示验证码识别的具体过程。
(1) 点击 在浏览器中打开打码平台网页,并且单击首页的 用户注册
按钮,如下图所示。
(3) 账号注册完成以后,在网页的顶部导航栏中选择 开发文档
,然后在常用开发语言示例下载中选择 Python
语言,如下图所示。
点击这里下载
超链接即可下载示例代码,如下图所示。 # -*- coding: UTF-8 -*-"""@author:AmoXiang@file:2.chaojiying.py@time:2021/01/19"""import requests # 网络请求模块from hashlib import md5 # 加密class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username # 自己注册的账号 password = password.encode('utf8') # 自己注册的密码 self.password = md5(password).hexdigest() self.soft_id = soft_id # 软件ID self.base_params = { # 组合表单数据 'user': self.username, 'pass2': self.password, 'softid': self.soft_id, } self.headers = { # 请求头信息 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)', } def PostPic(self, im, codetype): """ im: 图片字节 codetype: 题目类型 参考 http://www.chaojiying.com/price.html """ params = { 'codetype': codetype, } params.update(self.base_params) # 更新表单参数 files = { 'userfile': ('ccc.jpg', im)} # 上传验证码图片 r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers) return r.json() # 返回响应数据 def ReportError(self, im_id): """ im_id:报错题目的图片ID """ params = { 'id': im_id, } params.update(self.base_params) r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers) return r.json()
(6) 在已经确保用户名完成充值的情况下,填写必要参数,然后创建实例代码中的实例对象,实现验证码的识别工作。代码如下:
if __name__ == '__main__': # 用户中心>>软件ID 生成一个替换 96001 chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001') im = open('a.jpg', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要// # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加() print(chaojiying.PostPic(im, 1902))
(7) 使用平台示例代码中所提供的验证码图片,运行以上示例代码,程序运行结果如下:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '6129521154616800019', 'pic_str': '7261', 'md5': 'cc4e43a6905b3a447436b273a3ea121b'}
说明:程序运行结果中 pic_str 所对应的值为返回的验证码识别信息。
在发送识别验证码的网络请求时,代码中的 1902
表示验证码类型,该平台支持所有的常用验证码类型点击 可进行查询。
滑动拼图验证码是在滑动验证码的基础上增加了滑动距离的校验,用户需要将图形滑块滑动至主图空缺滑块的位置,才能通过校验。下面以测试地址对应的网页为例,实现滑动拼图验证码的自动校验,具体步骤如下:
测试网页地址如下:
http://sck.rjkflm.com:666/spider/jigsaw/
(1) 使用浏览器打开测试网页的地址,将显示如下图所示的滑动拼图验证码。
按钮滑块/图形滑块
以及 空缺滑块
所对应的 HTML 代码标签所在的位置,如下图所示。 # -*- coding: UTF-8 -*-"""@author:AmoXiang@file:demo3.py@time:2021/01/19"""from selenium import webdriver # 导入webdriverimport re # 导入正则模块driver = webdriver.Chrome() # 谷歌浏览器driver.get('http://sck.rjkflm.com:666/spider/jigsaw/') # 启动网页swiper = driver.find_element_by_xpath( '/html/body/div/div[2]/div[2]/span[1]') # 获取按钮滑块action = webdriver.ActionChains(driver) # 创建动作action.click_and_hold(swiper).perform() # 单击并保证不松开# 滑动0距离,不松手,不执行该动作无法获取图形滑块left值action.move_by_offset(0, 0).perform()# 获取图形滑块样式verify_style = driver.find_element_by_xpath( '/html/body/div/div[2]/div[1]/div[1]').get_attribute('style')# 获取空缺滑块样式verified_style = driver.find_element_by_xpath( '/html/body/div/div[2]/div[1]/div[2]').get_attribute('style')# 获取空缺滑块left值verified_left = float(re.findall('left: (.*?)px;', verified_style)[0])# print(verified_left)# 获取图形滑块left值verify_left = float(re.findall('left: (.*?)px;', verify_style)[0])# print(verify_left)action.move_by_offset(verified_left - verify_left, 0) # 滑动指定距离action.release().perform() # 松开鼠标
好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
如果我的博客对你有帮助、如果你喜欢我的博客内容,请点赞
、评论
、收藏
一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。 编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注
我哦!
转载地址:http://irx.baihongyu.com/