一、tesseract dll下载
https://github.com/charlesw/tesseract 这个网址中包含了编译好的exe及dll文件,而且x86,x64两种架构都有。
(特别说明:选择x86还是x64版本dll,只依赖于你的python架构,而不是操作系统的架构,即便是在64位操作系统,假如你的python是32位版本,这里也要选用x86版本dll)。
下载这两个DLL:libtesseract304.dll 和 liblept172.dll
二、语言包下载
网址: https://github.com/tesseract-ocr/tessdata ,下载其中需要的语言包就行了。跟dll放到同一目录 ( 记得把语言包放在tessdata文件夹里面 ) 。
语言包文件格式:eng.traineddata
以上网址打不开的请自行百度关键字:GitHub不能访问
三、vc 2015++发行包下载
注意说明里这一段话:
Since tesseract and leptonica binaries are compiled with Visual Studio 2015 you'll need to ensure you have theVisual Studio 2015 Runtimeinstalled.
意思就是,这个tesseract 的dll是使用vs 2015编译的,所以必须安装其发行包,同样分X64,X86两个版本,还是依赖于你的开发环境,不依赖于操作系统。
四、安装pyocr for python包
用pip就可以安装: pip install pyocr,也可以到官网下载源码,手动安装:https://github.com/jflesch/pyocr
最新的pyocr是0.4.1,其源码还是基于tesseract 3.0.2 ,而前文下载的tesseract 已经是3.0.4版本了,所以需要改下pyocr源码。(需要说明的是pyocr包,比起pytesseract包要更复杂一些,同时支持shell、api 、Cuneiform三种形式。)
----------------------------------------------我是分割线----------------------------------------------
上面都是复制的,红色是我特别说明的。
下面开始贴代码:
我这里创建了两个py文件,MainWindow.py、Logon_Test.py
MainWindow.py代码:
# -*- coding: utf-8 -*-
import Logon_Test
if __name__ == '__main__':
LoginURL = 'http://######/psdr/login.do?method=enterbs' # 登陆提交地址
CodeImgURL = 'http://######/psdr/form/digitalverify.jsp' # 验证码获取地址
url = 'http://######/psdr/projectInfo.do?method=queryTrace' # 项目展示地址
loginId = "用户名"
password = "密码"
a = Logon_Test.CDRS_Logon(LoginURL,CodeImgURL,loginId,password,True)
img = a.get_VerificationCode_Image()
Code = a.ImageToString(img)
#对验证码的识别进行判断
i = 1
while Code == "" or not(Code.isdigit()):
i += 1
img = a.get_VerificationCode_Image()
Code = a.ImageToString(img)
if i > 5 :
break
a.set_PostData_And_send(Code)
source_file = a.get_Web_source_file(url)
print(source_file)
这个文件很简单,就是类初始化、类方法的调用。
我们主要看Logon_Test.py文件的实现:
# -*- coding: utf-8 -*-
try:
import requests, base64, re, os, sys
from PIL import Image, ImageDraw
from io import BytesIO
from pyocr import libtesseract
from pyocr.builders import TextBuilder
except ImportError:
print("ImportError!")
raise SystemExit
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
elif __file__:
application_path = os.path.dirname(__file__)
tessdir = os.getenv('TESSDATA_PREFIX', None)
if tessdir is None :
os.environ['TESSDATA_PREFIX'] = application_path
if application_path not in os.environ['PATH']:
os.environ['PATH']= application_path + ';' +os.environ['PATH']
class CDRS_Logon:
#模拟登陆的类
def __init__(self, LoginURL, CodeImgURL, LoginId, Password, base64_utf_8 = False):
self.LoginURL = LoginURL
self.CodeImgURL = CodeImgURL
if base64_utf_8 == True: # base64_utf_8参数判断是否需要进行转码(根据网站需要)
base64_loginId_utf_8 = base64.b64encode(LoginId.encode('utf-8'))
base64_password_utf_8 = base64.b64encode(Password.encode('utf-8'))
ID = re.findall(r'b\'(.*)\'', str(base64_loginId_utf_8)) #用正则处理掉标识符b'
PWD = re.findall(r'b\'(.*)\'', str(base64_password_utf_8))
self.LoginId = ID[0]
self.Password = PWD[0]
else:
self.LoginId = LoginId
self.Password = Password
self.session = requests.session() # 创建统一的会话
self.Code = "null"
def get_VerificationCode_Image(self):
#获取验证码图片
res = self.session.get(self.CodeImgURL, stream=True) # 获取验证码图片
img = Image.open(BytesIO(res.content))
return img
def ImageToString(self,img):
bu = TextBuilder(tesseract_layout=7)
vcode = libtesseract.image_to_string(img, , builder=bu)
return vcode
def set_PostData_And_send(self, Code):
# 构建POST数据并提交
postData = {'txtLoginId': '', 'loginId': self.LoginId,
'txtPassword': '', 'password': self.Password,
'vericode': Code, 'chkLoginuser': 'on'}
self.session.post(self.LoginURL, postData)
def get_Web_source_file(self, get_URL):
#获取网页源文件
Web_source_file_Res = self.session.get(get_URL)
return Web_source_file_Res.text
我再对其中的关键部分解释一下。
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
elif __file__:
application_path = os.path.dirname(__file__)
tessdir = os.getenv('TESSDATA_PREFIX', None)
if tessdir is None :
os.environ['TESSDATA_PREFIX'] = application_path
if application_path not in os.environ['PATH']:
os.environ['PATH']= application_path + ';' +os.environ['PATH']
上面这段代码用于判断当前文件是py脚本文件还是可执行文件(exe),因为这两个不同的文件,在运行中取得的文件路径是不同的,这是很关键的地方,不然就会导致无法找到tessdata文件夹,运行错误。
接着第二段创建了环境变量,用于引导语言包和DLL文件的调用。
构造函数中base64_utf_8参数是我实验的网站需要处理的,通过查看网站源码发现对用户名和密码进行了转码,所以我也处理了一下。实际情况,按看客自己的要求来处理。
def ImageToString(self,img):
bu = TextBuilder(tesseract_layout=7)
vcode = libtesseract.image_to_string(img, , builder=bu)
return vcode
上面代码中
vcode = libtesseract.image_to_string(img, , builder=bu)
lang参数默认也是英语,这里设置为自己要用的语言包,但一定要下载好对应的语言包文件。
----------------------------------------------我是分割线----------------------------------------------
上面的程序已经可以作为脚本运行了。接下来我们进行exe文件的打包处理。
PyInstaller是一个十分有用的第三方库,它能够在Windows、Linux、Mac OS X 等操作系统下将 Python 源文件打包,通过对源文件打包,Python 程序可以在没有安装 Python 的环境中运行,也可以作为一个独立文件方便传递和管理。PyInstaller 需要在命令行(控制台)下用pip 工具安装,如下:
pip install pyinstaller
安装完成后cd到脚本文件的目录下执行打包命令:
pyinstaller -F MainWindow.py
执行完成后会生产两个目录build和dist,其中后一个目录里面就有可执行文件了。
接下来我们试验一下。把可执行文件(MainWindow.exe)复制出来,然后把前面开头我们准备的tessdata文件夹和liblept172.dll、libtesseract304.dll也复制出来,放在同一个文件夹下。这里也要注意一下,整个文件的路径不要有中文,不然在环境变量的设置时会出错。
用CMD运行我们的MainWindow.exe文件,就可以看到执行结果了。当然,你也可以直接双击,不过窗口可能会一闪而逝。