Python3实现自动查询成绩(主要使用的包有Tesseract-OCR、PIL、execjs、pytesseract、BeautifulSoup)
前提:本文仅作为技术训练,不可利用技术做非法的事。
某考试的成绩查询页面如下:查询成绩需要的数据有准考证号或者身份证、考生姓名、验证码。现在使用python来实现自动查询指定人员的考试成绩(不知道准考证号的前提下)。主要使用的包有Tesseract-OCR、PIL、execjs、pytesseract、BeautifulSoup
查询页面:

入围名单:

包的功能介绍:
- execjs:由于查询成绩参数加密后发送给服务器,这里使用调用原网站的加密函数加密查询字符串。
- BeautifulSoup:建立爬取的网页的文档树。
- PIL:中的Image函数读取下载下来的验证码图片,实例化后传给Tesseract-OCR识别。
- Tesseract-OCR:读取图片验证码,识别图片中的数字(主要其中有图片的训练集)。
- pytesseract:tesseract_cmd来初始化Tesseract-OCR,然后使用image_to_data()方法识别图片中的数字,该方法接受Image实例化后的图片对象为参数。
第一步:安装环境
主要介绍Tesseract-OCR安装,其他包可通过pip+包名自行安装。
安装完成后将Tesseract-OCR添加进path环境变量;然后新建环境变量TESSDATA_PREFIX:安装目录\Tesseract-OCR\tessdata。然后重启计算机。
cmd输入tesseract显示如下则安装成功:

第二步:登陆网站收集信息
使用正确的账号信息登陆,收集header、cookies及其他信息(例如本次登陆就使用到加密的js)。
- 加密js信息:(根据发送的查询字符串是否需要加密来决定是否添加)
JSCode = r'''
/*
*(1).加密:
* 第一步:strEncode(data,firstKey,secondKey,thirdKey);
*(2).解密:
* 第一步:strDecode(data,firstKey,secondKey,thirdKey);
*/
/*
* encrypt the string to string made up of hex
* return the encrypted string
*/ 中间内容略 /*end*/ '''
- header相关信息
header = {
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Cookie': 'JSESSIONID=E9A7EF615C2A7FC0D99711C8697D158B',
'Host': '***.***.***.***',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
- 在python中可以使用如下方式调用js中的代码:
#装载
CTX = execjs.compile(JSCode) #调用
CTX.call('函数名', '实参')
第三步:模拟登陆(考号+姓名+验证码)
为了将准考证号中隐藏的数字找出来,我们需要不断遍历。直到考号跟姓名对应。
这里的验证码在访问成绩页面时就产生了,所以需要所以使用requests.get(url1, headers=header)来将验证码下载到本地,然后识别出来,接着在模拟查询按钮动作 requests.get(url2, headers=header)
,将所有信息塞入查询字符串进行查询,由于是遍历查询,一旦循环产生的考号与已知的姓名匹配,就会返回结果,查询结束。
- 模拟登陆,并返回查询结果req2.text:
def get_content(number='', name='张三'):#填入一个正确的默认信息
number = CTX.call('strEncode', number) #调用js加密数字,以下类同
name = CTX.call('strEncode', name)
url1 = 'http://***.***.***.***/2019****/register/image.jsp'
header = null #略
while True:
try:
req1 = requests.get(url1, headers=header)
img = req1.content
with open('./yanzhengma.png', 'wb') as f:
f.write(img)
im = Image.open(r'D:\PycharmProjects\untitled1\yanzhengma.png')
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
num = pytesseract.image_to_data(im) #识别验证码中的数字
input_yznumber = num[-4:] #将结果的最后四位数字取出,即验证码 yznumber = CTX.call('strEncode', input_yznumber)
url2 = 'http://***.***.***.***/2019****/printInfo.do?activity=cjddy&number=' + number + '&name=' + name + '&yznumber=' + yznumber
req2 = requests.get(url2, headers=header)
req2.encoding = 'utf-8'
break
except socket.timeout as e:
print('3:', e)
time.sleep(random.choice(range(8, 15)))
except socket.error as e:
print('4:', e)
time.sleep(random.choice(range(20, 60)))
except http.client.BadStatusLine as e:
print('5:', e)
time.sleep(random.choice(range(30, 80)))
except http.client.IncompleteRead as e:
print('6:', e)
time.sleep(random.choice(range(5, 15)))
return req2.text
- 使用BeautifulSoup遍历文档树:
遍历文档树后查询指定dom(本例是div)下的内容:
def get_data(xml_data):
bs = BeautifulSoup(xml_data, "html.parser")
scores = bs.find_all('div', string=re.compile('')) #考号的前几位
return scores
- 启动程序,遍历查询
if __name__ == "__main__":
for kc in range(3000, 4601): #考场号 范围可从0-9999 根据考号规则改变
for zwh in range(0, 1000): #最大座位号是999
if len(str(zwh)) == 1:
number = ''+str(kc)+''+str(zwh)
elif len(str(zwh)) == 2:
number = ''+str(kc) + ''+str(zwh)
else:
number = ''+str(kc) + str(zwh)
print("number = ", number)
zhunkaohao = get_data(get_content(number='' + str(zwh)+'', name='焦作'))
if zwh % 50 == 0:
t_zhunkaohao=get_data(get_content(number='', name='张三')) #每50次返回一个正确结果,来确保查询正确性
print("***************"+str(t_zuoweihao))
if zhunkaohao != []:
print(zhunkaohao)
break #查询成功 跳出循环
由于涉密,这里就不附上源码了。
需要引入以下包:
# coding: utf-8
import socket
from bs4 import BeautifulSoup
import requests, random, time, http
import execjs
import re
import pytesseract
from PIL import Image
参考:
Python3实现自动查询成绩(主要使用的包有Tesseract-OCR、PIL、execjs、pytesseract、BeautifulSoup)的更多相关文章
- Oracle数据库作业-6 查询成绩比该课程平均成绩低的同学的成绩表
33. 查询成绩比该课程平均成绩低的同学的成绩表. select * from score a where a.degree between 0 and( select avg(degree) fro ...
- 在Android上模拟登录广工正方教务系统查询成绩
这是在博客园里开博以来写的第一篇博客. 因为之前看过很多人都有发过关于模拟登录正方软件获取数据的文章,自己觉得挺好玩的便也去动手一做,开始还以为挺难的,但实际做起来还蛮简单的,当然其中还有些小插曲. ...
- Android Tasker应用之自动查询并显示话费流量套餐信息
Android Tasker应用之自动查询并显示话费流量套餐信息 虽然Android平台有非常多的流量监控软件,但最准确的流量数据还是掌握在运营商手里.有些朋友可能像我一样时不时地发短信查询流量信息, ...
- PS_Form个性化选择Block自动查询和查询条件排序实现(案例)
2014-06-01 BaoXinjian
- 使用Python3导出MySQL查询数据
整理个Python3导出MySQL查询数据d的脚本. Python依赖包: pymysql xlwt Python脚本: #!/usr/bin/env python # -*- coding: utf ...
- UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包
背景 项目上需要做UWP的自动安装包,在以前的公司接触的是TFS来做自动build. 公司要求用Jenkins来做,别笑话我,之前还真不晓得这个东西. 会的同学请看一下指出错误,不会的同学请先自行脑补 ...
- eclipse android 不会自动生成R.java文件和包的解决办法
eclipse下编写android程序突然不会自动生成R.java文件和包的解决办法 我的eclipse原来是好好的,什么问题都没有的,结果今天一打开新建一个android程序,发现工程里不会自动 ...
- mysql查询进程、导入数据包大小设置
mysql查询进程.导入数据包大小设置 zoerywzhou@163.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2017-12-27 查询正在执行的进程: ...
- ROS知识(16)----如何编译时自动链接同一个工作空间的其他包的头文件(包含message,srv,action自动生成的头文件)
catkin_make编译时,往往需要自动链接同一个工作空间的其他包的头文件.否则会出现类似如下的错误: /home/xx/xx_ws/srcA_package/src/db.hpp:13:26: f ...
随机推荐
- Python3正则表达式
正则表达式是一个特殊的字符序列,他能帮助你方便的检查一个字符串是否与某种模式匹配. re.match函数 re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,matc ...
- ora-28000:the account is locked,Oracle修改密码有效期,Oracle设置密码不过期
查询Oracle用户是否被锁定 --例如我这里是VMCXEDDB 是否被锁定 select username,account_status,lock_date from dba_users where ...
- HTTP请求响应的过程
1. TCP/IP协议分层结构 应用层(含括了OSI七层中的上三层,分别为应用层,表示层, 会话层):DNS, URI, HTML, HTTP, TLS/SSL, SMTP, POP, ...
- Android根据内网外网连接情况配置服务器访问IP
新项目的app,可通过内网和外网的服务器ip进行请求访问,但是客户提供了专业终端,终端在wifi情况下走外网内网都可以,但关闭wifi则只能走4G专网,也就是只能走内网. 可前往我的小站查看:Andr ...
- 响应面分析 | response surface analysis | R代码
先开题,慢慢补充. 参考: 什么是响应面(RSM)分析 Response-Surface Methods in R, Using rsm In-class Examples with R Code R ...
- jsch连接sftp后连接未释放掉问题排查
项目中通过jsch中的sftp实现上传下载文件.在压测过程中,由于调用到sftp,下载文件不存在时,系统不断抛出异常,内存飙升,逐渐把swap区也占满,通过top监控未发现占用内存的进程,通过查找ss ...
- ubuntu上保存防火墙规则
与CentOS不同,ubuntu的iptables规则不是写在系统文件/etc/sysconfig/iptables 中的(至少1204 1404不是这样的) 保存: ubuntu的iptables建 ...
- Android点击事件通过kotlin几种实现方式总结
一般来说,Android点击事件通过kotlin有以下几种实现方式: 1.通过全局接口View.OnClickListener实现,代码如下 //class MainActivity : AppCom ...
- Dart 自增++自减--和循环语句
void main(){ /* ++ -- 表示自增 自减 1 在赋值运算里面 如果++ -- 写在前面 这时候先运算 再赋值,如果++ --写在后面 先赋值后运行运算 var a=10; var b ...
- pytorch nn.Sequential()动态添加方法
之前我们使用nn.Sequential()都是直接写死的,就如下所示: # Example of using Sequential model = nn.Sequential( nn.Conv2d(, ...