验证码反爬虫,python反爬技术
特斯拉CT-OCR是一款免费开源的OCR引擎,通过它你可以识别图片中的验证码。本文主要介绍Python反爬机制——验证码的样例代码,有需要的朋友可以参考一下。
00-1010识别验证码1。人物验证码1.1OCR环境1.2下载验证码图片1.3身份验证码2。第三方验证码的识别3。滑动拼图验证码
目录
OCR(Optical Character Recognition)是一种光学字符识别技术,专门用于识别图片中的字符并获取文本。字符验证码的特征是含有数字、字母或图片验证码,并混有斑点和混淆的曲线。识别这种验证码,首先需要在网页的HTML代码中找到验证码图片的位置,然后下载验证码,最后通过OCR技术识别验证码。
识别验证码
1. 字符验证码
萨特CT-OCR是一款免费开源的OCR引擎,通过它你可以识别图片中的验证码。构建OCR的具体步骤如下:
(1)这里以macOS操作系统为例,使用brew install安装tesseract。该命令如下所示:
luxiaowei @ macbook air ~ % brew Install-with-training-tools tessera CT #同时安装附加组件
安装完成后,使用以下命令对其进行测试,示例代码如下:
刘晓伟@MacBookAir ~ %宇宙魔方-v
宇宙魔方5.0.1
莱普尼卡-1.82.0
libgif 5 . 2 . 1 : libjpeg 9d : libpng 1 . 6 . 37 : libtiff 4 . 3 . 0 : zlib 1 . 2 . 11 : lib webp 1 . 2 . 1 : libopenjp 2 2 . 4 . 0
找到AVX2
找到AVX了
找到FMA了
找到SSE4.1
找到了lib archive 3 . 5 . 2 zlib/1 . 2 . 11 liblzma/5 . 2 . 5 bz2lib/1 . 0 . 8 liblz 4/1 . 9 . 3 libzstd/1 . 5 . 0
找到了libcurl/7 . 77 . 0 secure transport(libres sl/2 . 8 . 3)zlib/1 . 2 . 11 nghttp 2/1 . 42 . 0
(2)使用以下安装命令安装tesseract模块:
pip安装宇宙魔方
朔明
如果您正在使用Anaconda,并且在安装tesseract模块时出现错误,您可以使用以下命令:
conda install -c simonflueckiger宇宙魔方
1.1 OCR环境
以下面地址对应的网页为例,从网页下载验证码图片。具体步骤如下:
测试页面地址:3358 sck . rjkflm.com :666/spider/word/
(1)用浏览器打开测试网页的地址,会显示如下图所示的字符验证码:
(2)打开浏览器开发者工具,然后在HTML代码中获取验证码图片的位置,如下图所示:
(3)向目标网页发送网络请求,获取返回的HTML代码中图片的下载地址,然后下载验证码图片。代码如下:
#_*_coding:utf-8_*_
#作者:刘晓伟
#创建时间:2/15/22 7:47 PM
# File:获取HTML代码中的地址下载验证码picture.py
# IDE :PyCharm
#导入网络请求模块
我
mport requests
# 导入urllib.request模块
import urllib.request
# 导入随机请求头
from fake_useragent import UserAgent
# 导入ssl,否则ssl验证错误
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 导入解析HTML的模块
from bs4 import BeautifulSoup
# 创建随机请求头
header = {User-Agent:UserAgent().random}
# 网页请求地址
url = http://sck.rjkflm.com:666/spider/word/
# 发送网络请求
resp = requests.get(url, header)
resp.encoding = utf-8
# 解析HTML
html = BeautifulSoup(resp.text, html.parser)
src = html.find(img).get(src)
# 组合验证码图片请求地址
img_url = url+src
# 下载并设置图片名称
urllib.request.urlretrieve(img_url, code.png)
程序运行后项目文件夹中自动生成验证码图片,结果如下图:
1.3 识别验证码
验证码下载完成以后, 如果没有安装pillow模块,需要通过pip install pillow命令安装一下,如果tesserocr模块没安装也要通过"pip install tesserocr"先安装,然后导入tesserocr与Image模块,再通过Image.open()方法打开验证码图片,接着通过tesserocr.image_to_text()函数识别图片中的验证码信息即可。示例代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 7:21 AM
# 文件 :识别图中验证码.py
# IDE :PyCharm
# 导入tesserocr模块
import tesserocr
# 导入图像处理模块
from PIL import Image
# 打开验证码图片
img = Image.open(code.png)
# 将图片中的验证码转换为文本
code = tesserocr.image_to_text(img)
print(验证码为: , code)
程序运行结果如下:
验证码为: uuuc
Process finished with exit code 0
OCR的识别技术虽然很强大,但是并不是所有的验证码都可以这么轻松地识别出来,如下图所示的验证码中就会掺杂很多干扰线条,那么在识别这样的验证码信息时,就需要对验证码图片进行相应的处理并识别。
如果直接通过OCR识别,识别结果将会受到干扰线的影响,下面通过OCR直接识别测试一下效果。示例代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 8:23 AM
# 文件 :识别带干扰线的验证码.py
# IDE :PyCharm
import tesserocr # 导入tesserocr模块
from PIL import Image # 导入图像处理模块
img =Image.open(code2.jpg) # 打开验证码图片
img = img.convert(L) # 将彩色图片转换为灰度图片
img.show() # 显示灰度图片
code = tesserocr.image_to_text(img) # 将图片中的验证码转换为文本
print(验证码为:,code)
程序运行结果如下:
验证码为: YSGN. # 多了一个.
Process finished with exit code 0
通过以上测试发现,直接通过OCR技术识别后的验证码中多了一个‘.’,遇到此类情况手写可以将彩色的验证码图片转为灰度图片在测试一下。示例代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 8:29 AM
# 文件 :将彩色验证码图片转为灰度图片测试.py
# IDE :PyCharm
import tesserocr # 导入tesserocr模块
from PIL import Image # 导入图像处理模块
img =Image.open(code2.jpg) # 打开验证码图片
img = img.convert(L) # 将彩色图片转换为灰度图片
img.show() # 显示灰度图片
code = tesserocr.image_to_text(img) # 将图片中的验证码转换为文本
print(验证码为:,code)
程序运行结果如下:
验证码为: YSGN. # 依然多一个‘.‘
Process finished with exit code 0
接下来需要将转为灰度的验证码图片进行二值化处理,将验证码二值化处理后再次通过OCR进行识别。示例代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 8:38 AM
# 文件 :将验证码图片二值化处理.py
# IDE :PyCharm
import tesserocr # 导入tesserocr模块
from PIL import Image # 导入图像处理模块
img =Image.open(code2.jpg) # 打开验证码图片
img = img.convert(L) # 将彩色图片转换为灰度图片
t = 155 # 设置阀值
table = [] # 二值化数据的列表
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(验证码为:,code) # 打印验证码
程序运行后将自动显示二值化处理后的验证码图片
程序运行结果如下:
验证码为: YSGN
Process finished with exit code 0
说 明
在识别以上具有干扰线的验证码图片时,我们可以做一些灰度和二值化处理,这样可以提高图片的验证码的识别度,如果二值化处理后还是无法识别到精确性,可以适当的上下调节二值化操作的阙值。
2. 第三方验证码识别
针对OCR识别率和准确度不高的缺点,使用第三方验证码识别平台是一个不错的选择,不仅可以解决验证码识别率低低问题,还可以提高验证码识别的准确度。第三方平台识别验证码非常简单,平台提供了完善的API接口,根据平台对应的开发文档即可完成快速开发的需求,但每次验证码成功识别后平台会收取少量费用。
验证码识别平台一般分为两种,分别是打码平台和AI开发者平台。打码平台主要是由在线人员进行验证码的识别工作,然后在较短的时间内返回结果。AI开发者平台主要是由人工智能来进行识别。例如,百度AI。
下面以打码平台为例,演示验证码识别的具体过程。
(1)在浏览器中打开打码平台网页(http://www.chaojiying.com/),并且单击首页的用户注册按钮,如图所示:
(2) 然后在用户中心页面中填写注册账号的基本信息。如下图:
说 明
账号注册完成以后可以联系平台的客服人员,申请免费测试的题分。
(3) 账号注册完成以后,在网页的顶部导航栏中选择开发文档,然后在常用开发语言示例下载中选择Python语言,如下图所示:
(4) 在Python语音Demo下载页面中,查看注意事项,然后单击点击这里下载超链接即可下载示例代码,如图所示:
(5)平台提供的示例代码中,已经将所有需要用到的功能代码进行了封装处理,封装的代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 10:01 AM
# 文件 :平台提供识别封装代码.py
# IDE :PyCharm
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/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
params = {
codetype: codetype,
params.update(self.base_params) # 更新表单参数
files = {userfile: (code2.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
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()
if __name__ == __main__:
#用户中心>>软件ID 生成一个替换 96001
chaojiying = Chaojiying_Client(超级鹰用户名, 超级鹰用户名的密码, 928939)
im = open(a.jpg, rb).read() #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
#1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
print(chaojiying.PostPic(im, 1902))
(6)使用平台示例代码中所提供的验证码图片,运行以上示例代码,运行结果如下:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '9168810337948200001', 'pic_str': '7261', 'md5': '345c80a5dba345c219cc8893f19b496c'}
Process finished with exit code 0
说 明
程序运行结果中pic_str对应的值为返回的验证码识别信息。
在发送识别验证码的网络请求时,代码中的1902表示验证码的类型,该平台所支持的常用验证码类型如下表:
常用验证码类型
验证码类型验证码描述1902常见4-6位英文数字1101-10201-20位英文数字2001-20071-7位纯汉字3004-30121-12位纯英文4004-41111-11位纯数字5000不定长汉字英文数字51088位英文数字(包含字符)5201拼音首字母,计算题,成语混合5211集装箱号4位字母7位数字6001计算题6003复杂计算题
说 明
表中之列出了比较常用的验证码识别类型,详细内容可查验证码平台官网
3. 滑动拼图验证码
滑动拼图验证码是在滑动验证码的基础上增加了滑动距离的校验,用户需要将图形滑块滑动至主图空缺滑块的位置,才能通过校验。下面通过案例测试,实现滑动拼图验证码的自动校验。测试网页地址:http://sck.rjkflm.com:666/spider/jgsaw/
(1) 使用浏览器打开测试页的地址,将显示如图所示的滑动拼图验证码。
(2) 打开浏览器开发者工具,单击按钮滑块,然后在HTML代码中依次获取按钮滑块图形滑块以及空缺滑块所对应的HTML代码标签所在的位置。
验证码类型 验证码描述
(3)验证成功后的按钮滑块图形滑块以及空缺滑块位置变化如下所示
# 图形滑块<div class="verify" style="display: block; top: 30.2081px; background-position: -173.893px -30.2081px; left: 10px;"></div>
# 按钮滑块
<span class="swiper" style="left: 0px;"></span>
(4) 通过按钮滑块的left值可以确认需要滑动的距离,接下来只需要使用selenium框架模拟滑动的工作即可。实现代码如下:
#_*_coding:utf-8_*_# 作者 :liuxiaowei
# 创建时间 :2/16/22 5:19 PM
# 文件 :使用selenium框架模拟滑动图块.py
# IDE :PyCharm
from selenium import webdriver # 导入webdriver
import 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])
# 获取图形滑块left值
verify_left =float(re.findall(left: (.*?)px;,verify_style)[0])
action.move_by_offset(verified_left-verify_left,0) # 滑动指定距离
action.release().perform() # 松开鼠标
程序运行如下图显示:
总 结
到此这篇关于Python反爬机制-验证码的文章就介绍到这了,更多相关Python验证码反爬内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。