前提:本文仅作为技术训练,不可利用技术做非法的事。


某考试的成绩查询页面如下:查询成绩需要的数据有准考证号或者身份证、考生姓名、验证码。现在使用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信息:(根据发送的查询字符串是否需要加密来决定是否添加
  1. JSCode = r'''
  2. /*
  3. *(1).加密:
  4. * 第一步:strEncode(data,firstKey,secondKey,thirdKey);
  5. *(2).解密:
  6. * 第一步:strDecode(data,firstKey,secondKey,thirdKey);
  7. */
  8. /*
  9. * encrypt the string to string made up of hex
  10. * return the encrypted string
  11. */
  12.  
  13. 中间内容略
  14.  
  15. /*end*/
  16.  
  17. '''
  • header相关信息
  1. header = {
  2. 'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
  3. 'Accept-Encoding': 'gzip, deflate',
  4. 'Accept-Language': 'zh-CN,zh;q=0.9',
  5. 'Connection': 'keep-alive',
  6. 'Cookie': 'JSESSIONID=E9A7EF615C2A7FC0D99711C8697D158B',
  7. 'Host': '***.***.***.***',
  8. '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'
  9. }
  • 在python中可以使用如下方式调用js中的代码:
  1. #装载
  2. CTX = execjs.compile(JSCode)
  3.  
  4. #调用
  5. CTX.call('函数名', '实参')

第三步:模拟登陆(考号+姓名+验证码)

为了将准考证号中隐藏的数字找出来,我们需要不断遍历。直到考号姓名对应。

这里的验证码在访问成绩页面时就产生了,所以需要所以使用requests.get(url1, headers=header)来将验证码下载到本地,然后识别出来,接着在模拟查询按钮动作 requests.get(url2, headers=header)

,将所有信息塞入查询字符串进行查询,由于是遍历查询,一旦循环产生的考号与已知的姓名匹配,就会返回结果,查询结束。

  • 模拟登陆,并返回查询结果req2.text
  1. def get_content(number='', name='张三'):#填入一个正确的默认信息
  2. number = CTX.call('strEncode', number) #调用js加密数字,以下类同
  3. name = CTX.call('strEncode', name)
  4. url1 = 'http://***.***.***.***/2019****/register/image.jsp'
  5. header = null #略
  6. while True:
  7. try:
  8. req1 = requests.get(url1, headers=header)
  9. img = req1.content
  10. with open('./yanzhengma.png', 'wb') as f:
  11. f.write(img)
  12. im = Image.open(r'D:\PycharmProjects\untitled1\yanzhengma.png')
  13. pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'
  14. num = pytesseract.image_to_data(im) #识别验证码中的数字
  15. input_yznumber = num[-4:] #将结果的最后四位数字取出,即验证码
  16.  
  17. yznumber = CTX.call('strEncode', input_yznumber)
  18. url2 = 'http://***.***.***.***/2019****/printInfo.do?activity=cjddy&number=' + number + '&name=' + name + '&yznumber=' + yznumber
  19. req2 = requests.get(url2, headers=header)
  20. req2.encoding = 'utf-8'
  21. break
  22. except socket.timeout as e:
  23. print('3:', e)
  24. time.sleep(random.choice(range(8, 15)))
  25. except socket.error as e:
  26. print('4:', e)
  27. time.sleep(random.choice(range(20, 60)))
  28. except http.client.BadStatusLine as e:
  29. print('5:', e)
  30. time.sleep(random.choice(range(30, 80)))
  31. except http.client.IncompleteRead as e:
  32. print('6:', e)
  33. time.sleep(random.choice(range(5, 15)))
  34. return req2.text
  • 使用BeautifulSoup遍历文档树:

遍历文档树后查询指定dom(本例是div)下的内容:

  1. def get_data(xml_data):
  2. bs = BeautifulSoup(xml_data, "html.parser")
  3. scores = bs.find_all('div', string=re.compile('')) #考号的前几位
  4. return scores
  • 启动程序,遍历查询
  1. if __name__ == "__main__":
  2. for kc in range(3000, 4601): #考场号 范围可从0-9999 根据考号规则改变
  3. for zwh in range(0, 1000): #最大座位号是999
  4. if len(str(zwh)) == 1:
  5. number = ''+str(kc)+''+str(zwh)
  6. elif len(str(zwh)) == 2:
  7. number = ''+str(kc) + ''+str(zwh)
  8. else:
  9. number = ''+str(kc) + str(zwh)
  10. print("number = ", number)
  11. zhunkaohao = get_data(get_content(number='' + str(zwh)+'', name='焦作'))
  12. if zwh % 50 == 0:
  13. t_zhunkaohao=get_data(get_content(number='', name='张三')) #每50次返回一个正确结果,来确保查询正确性
  14. print("***************"+str(t_zuoweihao))
  15. if zhunkaohao != []:
  16. print(zhunkaohao)
  17. break #查询成功 跳出循环

由于涉密,这里就不附上源码了。

需要引入以下包:

  1. # coding: utf-8
  2. import socket
  3. from bs4 import BeautifulSoup
  4. import requests, random, time, http
  5. import execjs
  6. import re
  7. import pytesseract
  8. from PIL import Image

参考:

基于tesseract-OCR进行中文识别

加密js

Python3实现自动查询成绩(主要使用的包有Tesseract-OCR、PIL、execjs、pytesseract、BeautifulSoup)的更多相关文章

  1. Oracle数据库作业-6 查询成绩比该课程平均成绩低的同学的成绩表

    33. 查询成绩比该课程平均成绩低的同学的成绩表. select * from score a where a.degree between 0 and( select avg(degree) fro ...

  2. 在Android上模拟登录广工正方教务系统查询成绩

    这是在博客园里开博以来写的第一篇博客. 因为之前看过很多人都有发过关于模拟登录正方软件获取数据的文章,自己觉得挺好玩的便也去动手一做,开始还以为挺难的,但实际做起来还蛮简单的,当然其中还有些小插曲. ...

  3. Android Tasker应用之自动查询并显示话费流量套餐信息

    Android Tasker应用之自动查询并显示话费流量套餐信息 虽然Android平台有非常多的流量监控软件,但最准确的流量数据还是掌握在运营商手里.有些朋友可能像我一样时不时地发短信查询流量信息, ...

  4. PS_Form个性化选择Block自动查询和查询条件排序实现(案例)

    2014-06-01 BaoXinjian

  5. 使用Python3导出MySQL查询数据

    整理个Python3导出MySQL查询数据d的脚本. Python依赖包: pymysql xlwt Python脚本: #!/usr/bin/env python # -*- coding: utf ...

  6. UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包

    背景 项目上需要做UWP的自动安装包,在以前的公司接触的是TFS来做自动build. 公司要求用Jenkins来做,别笑话我,之前还真不晓得这个东西. 会的同学请看一下指出错误,不会的同学请先自行脑补 ...

  7. eclipse android 不会自动生成R.java文件和包的解决办法

    eclipse下编写android程序突然不会自动生成R.java文件和包的解决办法   我的eclipse原来是好好的,什么问题都没有的,结果今天一打开新建一个android程序,发现工程里不会自动 ...

  8. mysql查询进程、导入数据包大小设置

    mysql查询进程.导入数据包大小设置 zoerywzhou@163.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2017-12-27 查询正在执行的进程: ...

  9. ROS知识(16)----如何编译时自动链接同一个工作空间的其他包的头文件(包含message,srv,action自动生成的头文件)

    catkin_make编译时,往往需要自动链接同一个工作空间的其他包的头文件.否则会出现类似如下的错误: /home/xx/xx_ws/srcA_package/src/db.hpp:13:26: f ...

随机推荐

  1. golang go程和出让时间片

    golang go程和出让时间片 func main() { go func(){ //创建一个子go程 ;i<;i++{ fmt.Println("--------fuck U--- ...

  2. Spring boot 去除URL 里的 JSESSIONID

    方法一 application.yml 里设置 server: port: 80 servlet: session: tracking-modes: cookie cookie: http-only: ...

  3. file_get_contents("php://input")

    $data = file_get_contents("php://input");     php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最 ...

  4. PluginWindowlessWin

    实际绘图发生在我的本机代码中的屏幕外目标上,每次刷新都会调用myplugin :: onWindowRefresh,它会将StretchBlt调用到插件的无窗口窗口,代码如下, FB::PluginW ...

  5. Unity火爆插件Behavior Designer行为树插件学习

    如果要让游戏里的角色或者NPC能执行预设的AI逻辑,最简单的用IF..ELSE...神器既可以实现, 但是再复杂的一般用经典的状态机来切换状态,但是写起来比较麻烦.相对的,行为树(Behavior T ...

  6. Linux服务器下日志截取

    我们经常需要去Linux服务器上查看服务运行日志,但是有时候日志文件很大看起来很不方便,这个时候我们需要对日志进行切割筛选出自己需要的日志,比如查看某段时间内的日志,命令如下:   sed -n '/ ...

  7. MiniUI官方表单验证示例

    原文地址:http://www.miniui.com/docs/tutorial/validator.html 表单验证 参考示例: 验证规则     表单验证     表单验证:文本提示     表 ...

  8. tomcat中设置Java 客户端程序的http(https)访问代理

    1.假定http/https代理服务器为 127.0.0.1 端口为8118 2.在tomcat/bin/catalina.sh脚本文件中设置JAVA_OPTS,如下图: 保存后重启tomcat就能生 ...

  9. git如何查找某个包含指定字符串的commit hash值?

    答: git shortlog --format='%H|%cn|%s' | grep '需要查找的字符串内容'

  10. disruptor 单生产者多消费者

    demo1 单生产者多消费者创建. maven 依赖 <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --> < ...