本帖最后由 打字的小强 于 2020-6-11 14:05 编辑
最近爬虫遇到了字符图片混淆的反爬。如图所示,文字和图片混在一起,需要对图片进行识别,图片很小,这时候我就想到了pytesseract,一直知道但是从未去实际操作,今天讲讲基本步骤
一.搭建环境
tesseract是很多语言都可以调用的,简而言之是一个ocr本地识别引擎,所以要装本地环境,并不是pip install 就可以的。并不是python的专利,可以用这个训练自己的库,搭建环境还需要下载简体中文包
下载tesseract-ocr-setup-4.0.0-alpha.20180109.exe进行安装,可以选择安装位置,记住安装位置,我的位置是D:\minitool\Tesseract-OCR
下载简体中文识别库chi_sim.traineddata,放到安装位置的tesseract安装目录下tessdata的文件下
接下来做环境变量的配置,打开我的电脑,右键点击属性,计算机名,域工作组设置点击更改设置,点击高级,点击环境变量。在用户变量里面把tesseract安装目录添加进入path里面,在系统变量添加一个变量名为TESSDATA_PREFIX,变量值为字库存放目录的环境变量
接下来验证是否安装成功了里面输入 tesseract -v,如下图就是安装成功了
二.测试
找到所有的图片使用正则,我要把所有的标签和对应的字符做成一个python字典,后面就好替换
我这里只提供一个测试的例子
[Python] 纯文本查看 复制代码 def ocrs(names):
im = cv2.imread(names)
config = ("-l chi_sim --oem 0 --psm 10") #这些参数要做出说明的
datas = pytesseract.image_to_string(im, config=config) #调用pytesseract识别,
if datas: #判断有没有识别结果
c_datas = easygui.ccbox(msg='识别结果是' + datas, title=' ', choices=('True', 'false'),
image=names) #easygui一个询问框,人工确认是否识别正确
if not c_datas:
#如果识别不正确,enterbox人工输入,收集最终结果
datas = easygui.enterbox(msg="请输入正确的字:", title=' ', default=' ', strip=True,
image=names, root=None)
else:
# 如果pytesseract识别结果为空,enterbox人工输入,收集最终结果
datas = easygui.enterbox(msg="请输入正确的字:", title=' ', default=' ', strip=True,
image=names, root=None)
#返回最终结果。最坏的结果就是人工也没有输入
return datas
def img_to_string():
paths = "**********" #填写一个文本的路径,读取本文的信息,这里面有很多的标签
datas = open(paths, encoding='utf-8')
pattern = re.compile("<img.*?>") #找到所有img的正则
str2 = pattern.findall(datas) #找到所有的img标签
for i in str2:
#现在有很多的img的标签被匹配出来了
pattern = re.compile("/.*?\\.png") #正则找到其中的链接,图片文件格式都是png格式
str3 = pattern.findall(i) #正则找到其中的链接
urls = "*********"+str3[0] #*号是这个目标站点的域名,拼装起来,下面requests保存图片
if urls not in font_list : #为了防止同一个图片下载很多遍,过滤一下
font_list.append(urls) #没有就保存在数组里面,给上面判断
names = str3[0][17:-4] #提取图片的名称,保存文件的地方用
datass = requests.get(urls,verify=False) #下载图片
print(urls)
with open('./verify/' + str(names) + '.png', 'wb') as file:
file.write(datass.content) #保存图片的二进制的数据
result = ocrs('./verify/' + str(names) + '.png') #把文件脚本专门的识别函数识别,返回实际的识别的文字
if result:
print(result)
font_dict[i]=result #有结果就加入字典保存
else:
#人工也没有输入的结果
print("null")
font_dict[i] = "null"
效果图字库标记少,几十个文件公用20多个字,可以这样弄,先一一把对应关系找出来,在进行替换,下面的替换我就不讲了,写的比较垃圾,哈哈,不献丑了。下图就是效果,所有识别过都会记录到字典:
补充:
pytesseract调用的时候参数说明,这些参数我调了很久都没有准确的,完美的,后面只好做弹窗确认,我们的图片很小,只有一个字符。
--psm 10 这就是把整个图当一个字符来识别
--oem 0 旧的引擎,一共有四种,都试了,这种比较准
把参数列给大家看下
[Asm] 纯文本查看 复制代码 OCR选项:
--tessdata dir PATH指定tessdata PATH的位置。
--用户字路径指定用户字文件的位置。
--用户模式路径指定用户模式文件的位置。
--dpi值指定输入图像的dpi。
-l LANG[+LANG]指定用于OCR的语言。
-c VAR=配置变量的值设置值。
允许多个-c参数。
--psm NUM指定页面分段模式。
--oem NUM指定OCR引擎模式。
注意:这些选项必须在任何配置文件之前出现。
页面分割模式:
仅限0方向和脚本检测(OSD)。
1个带有OSD的自动页面分割。
2自动页面分割,但没有OSD或OCR。(未实施)
3全自动页面分割,但没有OSD。(默认)
4假设一列大小可变的文本。
5假设一个垂直对齐的文本块。
6假设一个统一的文本块。
7将图像视为单个文本行。
8将图像视为一个单词。
9将图像视为一个圆圈中的单个单词。
10将图像视为单个字符。
11稀疏文本。找尽可能多的文本没有特别的顺序。
12带OSD的稀疏文本。
13原始生产线。将图像视为单个文本行,
绕过特定于Tesseract的攻击。
OCR引擎模式:
仅限0旧版引擎。
仅限1台神经网络LSTM发动机。
2个传统+LSTM引擎。
3默认,基于可用的内容。
相关附件
链接:https://pan.baidu.com/s/13Ry_cDnbteIUHMr_33oi4w
提取码:fxfl
三.总结
Tesseract还是很方便的,还可以做一些其他的简单的验证码识别,网上也有很多的例子。一开始弄了半天,因为参数的问题,一直没有返回值,本来是想接入腾讯或者百度的第三方接口来识别的,结果发现并没有多少字。最后来在使用过程中加了一个群,里面还是有很多的其他用法,还可以用Tesseract训练出自己的字库,又涨见识了。
|