python 批量爬取四级成绩单
使用本文爬取成绩大致有几个步骤:1、提取表格(或其他格式文件——含有姓名,身份证等信息)中的数据,为进行准考证爬取做准备。2、下载准考证文件并提取出准考证和姓名信息。3、根据得到信息进行数据分析和存储。
所有需要的工具库:
import urllib
import requests
import xlrd
import json
import re
import time
import os
import operator from aip import AipOcr
from selenium import webdriver
from PIL import Image
准考证下载网址:http://cet-bm.neea.edu.cn/Home/QuickPrintTestTicket
使用查分数网址:http://cet.neea.edu.cn/cet/
具体实现:
一、提取姓名身份证信息并获取下载url关键信息
# 创建session访问对象
session = requests.session()
session.headers = {'打开对应网站http://cet-bm.neea.edu.cn/Home/QuickPrintTestTicket,复制cookies,必需!!!'} # 得到身份证和姓名信息 # 返回一个包含名字和id的列表
def get_name_id():
xls_data = xlrd.open_workbook(r'你的表格.xls')
tables = xls_data.sheets()[0]
for i in range('范围'):
rows = tables.row_values(i)
id = rows[7] # 对中文进行了url编码处理
name = urllib.parse.quote(rows[5])
yield [name, id] list_info = get_name_id() # 经过观察发现下载链接中只有一个sid参数有变化,所以我们下面筛选出sid参数并保存 # 需要手动到网站上点一个验证码, 时间大概在一分钟
# 到时后可能会有变动,请根据具体情况修改
yzm = '验证码' # 存储最终数据
data = [] for i in list_info: # 参数provinceCode是省份编码,请根据具体情况及时修改
# 另参数这里我没有用字典形式传入,所以中文转化成了url形式的
res = session.post('http://cet-bm.neea.edu.cn/Home/ToQuickPrintTestTicket',
data='Name={}&verificationCode={}&provinceCode=34&IDNumber={}&IDTypeCode=1'.format(i[0], yzm, i[1])) # 处理数据 以便存储
txt = res.content.decode('utf8')
txt = txt.replace('\\', '')
sid_one = re.findall("SID\":\"(.*?)\",", txt)[0] name_ = urllib.parse.unquote(i[0])
data.append({'name': name_, 'sid': sid_one}) with open("sid.json", 'w') as f:
f.write(json.dumps(data))
至此,我们得到了下载地址
二、下载文件并读取
with open('sid.json', 'r') as f:
sid = json.loads(f.read())
# 下载地址列表
urls = []
for i in sid:
url = 'http://cet-bm.neea.edu.cn/Home/DownTestTicket?SID={}'.format(i['sid'])
urls.append([url, i['name']])
for i in urls:
response = requests.get(i[0])
# 这里注意保存格式一定要写对!!!
# 不然是很头疼的一件事
with open(r'pdf\{}.zip'.format(i[1]), 'wb') as f:
f.write(response.content)
print('success')
这一步我们下载了准考证文件,注意最好创建一个新文件夹保存下载的文件,另外,前一篇写到的批量解压文件又用到了,自己修改一下即可
下面一段代码我们分析准考证号信息并另存为json文件
# 打开pdf文件并读取,网上很容易找到,这里也只做采用
def open_one_pdf(url):
# 定义变量接收我们所需的数据
admission_ticket_number = []
name = [] # 文件对象
pd_file = open(url, 'rb') # pdf文件解析对象
parser = PDFParser(pd_file) # print(parser)
# pdf文档对象
document = PDFDocument()
parser.set_document(document)
document.set_parser(parser) # 初始化文档密码
document.initialize()
if document.is_extractable:
print(True)
else:
raise PDFTextExtractionNotAllowed # 存储文档资源
src = PDFResourceManager() # 设备对象
device = PDFPageAggregator(src, laparams=LAParams()) # 解释器对象 inter = PDFPageInterpreter(src, device) pages = document.get_pages() # 总文本
str_total = '' for page in pages:
inter.process_page(page)
layout = device.get_result()
for x in layout:
if isinstance(x, LTTextBoxHorizontal):
str_total += str(x.get_text()) # 提取所需数据
admission_ticket_number.append(re.findall('准考证号:(.*?)\n', str_total, re.S)[0])
name.append(re.findall('姓名:(.*?)\n', str_total, re.S)[0]) return {'admission_ticket_number': admission_ticket_number, 'name': name} # 存储所有爬取对象的信息
data_list = [] for file in os.listdir('你的文件目录'):
if file.endswith('.pdf'):
# 斜杠别删了,这里没有使用os.path
data_list.append(open_one_pdf('你的文件目录\' + file))
else:
pass with open('admission_num.json', 'w') as f:
f.write(json.dumps(data_list))
到这里,我们得到了准考证信息
三、爬取成绩
# 百度api识别验证码
def deal_yzm():
""" 你的 APPID AK SK """
APP_ID = ''
API_KEY = ''
SECRET_KEY = ''
client = AipOcr(APP_ID, API_KEY, SECRET_KEY) def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read() url = r'yzm.png'
image = get_file_content(url) """ 调用文字识别, 图片参数为本地图片 """
x = client.basicAccurate(image)
# 一天500次,一般情况足够使用 # 设置时间间隔,减少出错率
time.sleep(1) # 筛选 这里的条件是识别出的结果只有一个且长度为4,请自行修改
if x['words_result_num'] == 1 and len(x['words_result'][0]['words'].replace(' ', '')) == 4:
return x['words_result'][0]['words'].replace(' ', '')
else:
return 'none' # 保存验证码
# webdriver提取元素的路径可能会有变动,使用前请检查
def save_yzm(img):
src_url = img.get_attribute('src')
response = requests.get(src_url)
with open('yzm.png', 'wb') as f:
f.write(response.content) # 几次试验得到的结果,可能转为灰度更易识别
I = Image.open('yzm.png')
L = I.convert('1')
L.save('yzm.png') # 保存失败和成功信息的列表
fail = [] while True: # 加载准考证和姓名信息
# 如果有失败记录文件则使用失败记录中的数据
if os.path.exists('fail.json'):
with open('fail.json', 'r') as f:
data = json.loads(f.read())
else:
with open('admission_num.json', 'r') as f:
data = json.loads(f.read()) # 有分数记录则继续添加
if os.path.exists('score.json'):
with open('score.json', 'r') as f:
score = json.loads(f.read())
else:
score = [] # 遍历列表中的准考证和姓名信息
for i in data: # 创建Chrome对象
driver = webdriver.Chrome() # driver等待时间
driver.implicitly_wait(3) number = i["admission_ticket_number"][0]
name = i['name'][0]
driver.get('http://cet.neea.edu.cn/cet/') # 获取元素
btn_id = driver.find_element_by_xpath('//*[@id="zkzh"]')
btn_name = driver.find_element_by_xpath('//*[@id="name"]')
btn_yzm = driver.find_element_by_xpath('//*[@id="verify"]')
btn_submit = driver.find_element_by_xpath('//*[@id="submitButton"]')
btn_id.send_keys(number)
btn_name.send_keys(name)
btn_yzm.click()
# 点击后验证码出现 # 等待加载
time.sleep(1)
img = driver.find_element_by_xpath('//*[@id="img_verifys"]')
# 保存图片 得到验证码
save_yzm(img) # 识别出的字符值
value = deal_yzm() # 处理识别失败的情况,有一类加入了干扰线,不好识别
# 这里选择刷新重复上传识别
while value == 'none':
img_change = driver.find_element_by_xpath('//*[@id="verifysStrDiv"]/a')
img_change.click()
time.sleep(1)
save_yzm(img)
value = deal_yzm() # 发送验证码并点击提交
btn_yzm.send_keys(value)
btn_submit.click() # 等待
time.sleep(1) # 因为登陆失败会有alert弹窗,driver会有错误提示,会结束程序,所以使用错误处理
try:
source = driver.page_source
except:
source = '' if '找出成绩单中的标志性信息,如学校等' not in source:
print('验证码获取不正确,请重新执行一次\n 失败id{}已保存至fail.json'.format(i))
fail.append(i)
driver.close()
continue # 筛选成绩
score_one = re.findall('<span id="s">(.*?)</span>', source, re.S)
print({'name': i['name'][0], 'score': score_one})
score.append({'name': i['name'][0], 'score': score}) driver.close() with open('fail.json', 'w') as f:
f.write(json.dumps(fail)) with open('score.json', 'w') as f:
f.write(json.dumps(score)) if not fail:
break
至此已经做完了数据的爬取,下面进行数据分析:
with open('score.json', 'r')as f:
data = json.loads(f.read())
sorted_x = sorted(data, key=operator.itemgetter('score'))
flag = 1
for i in sorted_x:
if i['score'][0] > '425' and flag == 1:
flag += 1
print("".center(60, '='))
print(i['name'] + '\t\t' + i['score'][0])
os.system('pause')
打印排序后的成绩,在第一个大于425的数后面加一个横线,暂停
代码和文章结构可能有些不调理,存在许多不足,使用时请自行修改
python 批量爬取四级成绩单的更多相关文章
- 从0实现python批量爬取p站插画
一.本文编写缘由 很久没有写过爬虫,已经忘得差不多了.以爬取p站图片为着手点,进行爬虫复习与实践. 欢迎学习Python的小伙伴可以加我扣群86七06七945,大家一起学习讨论 二.获取网页源码 爬取 ...
- python批量爬取动漫免费看!!
实现效果 运行环境 IDE VS2019 Python3.7 Chrome.ChromeDriver Chrome和ChromeDriver的版本需要相互对应 先上代码,代码非常简短,包含空行也才50 ...
- 用Python批量爬取优质ip代理
前言 有时候爬的次数太多时ip容易被禁,所以需要ip代理的帮助.今天爬的思路是:到云代理获取大量ip代理,逐个检测,将超时不可用的代理排除,留下优质的ip代理. 一.爬虫分析 首先看看今天要爬取的网址 ...
- python 批量爬取代理ip
import urllib.request import re import time import random def getResponse(url): req = urllib.request ...
- Python批量爬取谷歌原图,2021年最新可用版
文章目录 前言 一.环境配置 1.安装selenium 2.使用正确的谷歌浏览器驱动 二.使用步骤 1.加载chromedriver.exe 2.设置是否开启可视化界面 3.输入关键词.下载图片数.图 ...
- python批量爬取文档
最近项目需要将批量链接中的pdf文档爬下来处理,根据以下步骤完成了任务: 将批量下载链接copy到text中,每行1个链接: 再读txt文档构造url_list列表,利用readlines返回以行为单 ...
- python批量爬取猫咪图片
不多说直接上代码 首先需要安装需要的库,安装命令如下 pip install BeautifulSoup pip install requests pip install urllib pip ins ...
- 使用Python批量爬取美女图片
运行截图 实列代码: from bs4 import BeautifulSoup import requests,re,os headers = { 'User-Agent': 'Mozilla/5. ...
- from appium import webdriver 使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium)
使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium) - 北平吴彦祖 - 博客园 https://www.cnblogs.com/stevenshushu/p ...
随机推荐
- JS :Date日期格式化
Date.prototype.format = function (formatStr) { var date = this; /* 函数:填充0字符 参数:value-需要填充的字符串, lengt ...
- 安装weblogic中间件_test
小编对他还不是很了解,等了解的时候小编吧这句话删除(注意) 如果过程中有问题的话请联系 QQ:291562721 weblogic是ORACLE商家,他是一门中间件服务: 因为一些安全的原因,扫描发现 ...
- 【问题解决方案】关于Python中的语句 ' %matplotlib inline '
跟进小项目#GirlsInAI#-可视化时遇到的语句,之前没有遇到过 在Stack Overflow上看到了一个解释: IPython有一组预定义的"魔术函数",您可以使用命令行样 ...
- CSS-06 外部JS,CSS文件的寻址问题
如果js.css外部文件有使用到相对路径,其相对路径的基准是不一样的 当一个index.html中引入外部的JS和CSS文件时: 在index.css文件中,相对路径的写法是以css文件相对于img图 ...
- vue中监听返回键
问题:在项目中,我们常常有需求,当用户在填写表单时,点击返回的时候,我们希望加一个弹窗,确认离开吗,确认将保存为草稿 解决方案:利用 H5的 pushstate(个人理解为增加页面栈)特性与onpop ...
- ECMAScript严格模式
ECMAScript 第5个版本 1. 严格模式: 什么是: 比普通js运行机制,要求更严格的模式 为什么: js语言本身具有很多广受诟病的缺陷 何时: 今后所有的js程序,必须运行在严格模式下! 如 ...
- 脚本_检测mysql存活状态
#!bin/bash#功能:检测mysql服务是否存活#作者:liusingbon# host为你需要检测的mysql主机的IP 地址,user为mysql账户名,passwd为密码; 这些信息需要根 ...
- Android作业list
作业1. 请在自己的电脑上完成Android的安装与配置,并完成Hello Android项目.上交自己与项目的合照,将照片传至QQ群中. ------------------------------ ...
- CS184.1X 计算机图形学导论(第四讲)
一.齐次变换 1.平移变换 变换矩阵不能包含X,Y,Z等坐标变量 如果x坐标向右平移了5个单位长度,则x~=x+5.在变换矩阵中表示的时候添加一个w坐标变量.通过加入一个w坐标,可以实现平移变换 1& ...
- 【抓包工具之Fiddler】增加IP列;session高亮
Fiddler 在处理每个session时,脚本文件CustomRules.js中的方法都会运行,该脚本使得你可以隐藏,标识或任意修改负责的session.规则脚本在运行状态下就可以修改并重新编译,不 ...