使用python进行爬虫。需要修改一些参数。
原始数据存放在Excel表格中。
# -*- coding: utf-8 -*-
import urllib.request
import urllib.error
import http.cookiejar
from PIL import ImageTk
from PIL import Image as Image
from tkinter import *
import PIL
import tkinter as tk
import io
import os
import time
import xlrd
import openpyxl
from urllib import parse
import random
import json
# studentListExcel(studentList.xlsx)为学生信息表.该表结构如下:(第一行就应该开始放学生信息,不要有题头)
# |准考证号|姓名|
studentListExcel = '20级信息.xlsx'
# finalResult.xlsx为最终结果存储表,该表结构如下:(会自动生成题头)
# |准考证号|姓名|查询类型|大学名称|总分|听力|阅读|写作和翻译|口试准考证号|口试等级|
finalResultExcel = '20级2206六级成绩.xlsx'
# queryYear为查询成绩的年份。如要查询2019年上半年考试此变量应为2020.不要去掉引号
queryYear = '2022'
# queryTime为查询第几次考试。如要查询2019年上半年考试此变量应为1,下半年应为2.不要去掉引号
# 现更改为月份
queryTime = '06'
# passExamMark为及格线。大于等于此成绩为及格.
passExamMark = 425
# 默认查询类型 CET4/CET6,
# 科目
km = '1'
tobeCheckedCodeIMG = Image
finalResultRes = ""
success = 0
passexam = 0
headers = {
"Content-type": "application/x-www-form-urlencoded",
'Accept-Language': 'zh-CN,zh;q=0.8',
"Cache-Control": "no-cache",
"origin": "https://cjcx.neea.edu.cn",
"referer": "https://cjcx.neea.edu.cn",
"Referer": "http://cet.neea.edu.cn/cet/"
}
# 验证码窗口相关代码
class GetCode(object):
def __init__(self):
global tobeCheckedCodeIMG
global nowCode
print("请在新窗口中输入验证码...")
self.data={} # 存放返回值
self.root = tk.Tk()
self.root.geometry('230x200')
self.root.resizable(width=False,height=False) # 固定长宽不可拉伸
self.textLabel=tk.Label(self.root,text="输入验证码后按下回车(看不清直接回车)").pack() # 标签
self.textStr=StringVar()
self.textEntry=tk.Entry(self.root,textvariable=self.textStr) # 创建输入框
self.textStr.set("") # 清空输入框
self.textEntry.pack() # 输入框
self.textEntry.bind('<Return>', self.return_code) # 回车键按下自动递交
self.textEntry.focus_set() # 设置焦点
im=PIL.Image.open(io.BytesIO(tobeCheckedCodeIMG))
img=ImageTk.PhotoImage(im)
tk.Label(self.root,image=img).pack() # 显示图片
self.root.protocol('WM_DELETE_WINDOW', doNothing) # 禁止关闭
self.root.mainloop()
def return_code(self, x):
global nowCode
# 返回输入框内容
self.data["code"]=self.textStr.get()
if(len(self.data["code"]) == 0):
self.data["code"] = "NNNN"
self.root.destroy() # 关闭窗体
nowCode = self.data["code"]
def doNothing():
return
# 验证码窗口结束
# 爬取页面代码
def getPage(resultReq):
finalRequlstRes = "ERROR"
try:
finalResultRes = urllib.request.urlopen(resultReq).read().decode("utf-8") # 发送请求并保存页面
except Exception as e:
print("遇到HTTP错误:" + str(e))
print("等待一秒")
time.sleep(1) # 等待1秒
getPage(resultReq)
else:
# 开始检查返回页面正确性
if (str(finalResultRes).find('核实后') != -1):
# 信息不正确
print("请重新核实信息!")
finalResultRes = ""
else:
# 信息正确,开始检查验证码
if (str(finalResultRes).find('验证码错误') == -1):
# 验证码正确
print("检查通过!")
else:
# 验证码错误
print("验证码错误!")
finalResultRes = "ERROR"
return finalResultRes
# 爬取页面代码结束
cxlx = 'CET'
if not os.path.exists(studentListExcel):
print("学生信息表不存在!")
exit()
# 读取xlsx表中信息并存入列表
sheet = xlrd.open_workbook(studentListExcel)
table = sheet.sheets()[0] # 打开Sheet1
nrows = table.nrows # 查询总行数
allStudents = nrows
# 第一名学生插入List中为第0个
print("正在读取第1个学生,准考证号:"+table.col_values(0)[0]+" 姓名:"+table.col_values(1)[0])
studentList = [[table.col_values(0)[0], table.col_values(1)[0]]]
# 从第二名(List中第1个)开始循环读取到最后一名学生插入List中
i = 1
while i < allStudents:
print("正在读取第"+str(i+1)+"个学生,准考证号:"+table.col_values(0)[i]+" 姓名:"+table.col_values(1)[i])
studentList.append([table.col_values(0)[i], table.col_values(1)[i]])
i = i + 1
print("本次共导入"+str(allStudents)+"个学生")
print("正在打开存储数据文件...")
workbook = openpyxl.Workbook() # 打开表
sheet = workbook.active # 默认的第一张sheet
rawList = []
sheet.append(['准考证号','姓名','查询类型','大学名称','总分','听力','阅读','写作和翻译','口试准考证号','口试等级'])
workbook.save(finalResultExcel) # 记得保存数据
workbook = openpyxl.load_workbook(finalResultExcel) # 读取新建的文件
sheet = workbook.active
print("准备完成。")
queryYearTmp = input("本程序查询为"+queryYear+"年考试,是否正确?正确请直接按回车,不正确请输入年份后两位后回车。")
if queryYearTmp.isdecimal():
if(len(queryYearTmp) == 4):
queryYear = queryYearTmp
print("输入了"+queryYear)
else:
print("输入只能为4位数!退出.")
exit()
elif len(queryYearTmp) == 0 or queryYearTmp.isspace():
print("无输入,继续")
else:
print("输入非数字!退出.")
exit()
queryTimeTmp = input("本程序查询为当年"+queryTime+"月份考试。上半年为06,下半年为12.正确请直接按回车,不正确请输入06或12后回车。")
if queryTimeTmp == '06' or queryTimeTmp == '12':
queryTime = queryTimeTmp
print("输入了"+queryTime)
elif queryTimeTmp == 6 or queryTimeTmp == 12:
queryTime = str(queryTimeTmp)
print("输入了" + queryTime)
elif len(queryTimeTmp) == 0 or queryTimeTmp.isspace():
print("无输入,继续")
else:
print("输入错误!只能输入06或12,退出.")
exit()
print("开始爬取。")
j = 0
while j < allStudents:
# 开始准备...
time.sleep(0.5)
zkzh = str(studentList[j][0])
xm = studentList[j][1]
zkzh_parse = parse.quote(zkzh)
print("进度: 第"+str(j+1)+"个,共"+str(allStudents)+"个。正在爬取: 姓名:" + xm + " 准考证号: " + zkzh + " 查询类型: "+cxlx)
mainUrl = 'http://cachecloud.neea.edu.cn/api/latest/results/cet'
captchaUrl = 'http://cachecloud.neea.edu.cn/Imgs.do?c=CET&ik='+zkzh+'&t='+str(random.random())
print("本次查询使用url: " + mainUrl)
# 开始请求
resultPage = "ERROR"
while (resultPage == "ERROR"):
dataUrl = "http://cachecloud.neea.cn/api/latest/results/cet?"+"&km="+km+"&no="+zkzh+"&xm="+urllib.parse.quote(xm[:3])+"&v="
#dataUrl = "http://cachecloud.neea.edu.cn/api/latest/results/cet?e=CET_"+queryYear+queryTime+"_DANGCI&km="+km+"&no="+zkzh+"&xm="+urllib.parse.quote(xm[:3])+"&v="
print("获取成绩Url: "+dataUrl)
# 构建请求
resultReq = urllib.request.Request(url=dataUrl, headers=headers)
resultPage = str(getPage(resultReq)) # 返回结果
# 判断是否信息不正确
if (resultPage == ""):
# 信息确实不正确,标记上
rawList = [zkzh, xm, cxlx, "核实信息"]
sheet.append(rawList) # 追加一行
print("正在保存...")
workbook.save(finalResultExcel) # 记得保存数据
else:
# 信息正确,洗数据吧。
#print("正在提取成绩信息...信息原文: "+resultPage)
print("正在提取信息: "+resultPage)
try:
resultJson = json.loads(resultPage)
except Exception as e:
print("解析结果发生错误: "+str(e))
rawList = [zkzh, xm, cxlx, "接口错误: "+str(e)+" R:"+resultPage]
else:
success = success + 1
#['准考证号','姓名','查询类型',
# '大学名称','总分','听力','阅读','写作和翻译','口试准考证号','口试等级']
rawList = [resultJson['id'], xm, resultJson['km'], resultJson['xx'], resultJson['score'], resultJson['sco_lc'], resultJson['sco_rd'],
resultJson['sco_wt'], resultJson['ky_zkz'], resultJson['ky_sco']]
if (int)(resultJson['score']) < passExamMark:
print("该学生未通过!")
else:
passexam = passexam + 1
print(rawList) # 输出一下
sheet.append(rawList) # 追加一行
print("正在保存...")
workbook.save(finalResultExcel) # 记得保存数据
j = j + 1 # 别忘了自增开始下一名学生的处理。
try:
passRate = passexam / success
except Exception as e2:
passRate = 0
print("nothing")
rawList = ['', '总计', '成功获取:', success, '通过考试人数:', passexam, '通过率', str(passRate*100)+'%']
print("任务结束! 查询考试类型: "+cxlx+" "+queryYear+"年"+queryTime+"月")
print("总计"+str(allStudents)+"个学生, 成功获取"+str(success)+"个学生, 有"+str(passexam)+"个学生通过考试. 通过率"+str(passRate*100)+"%")
sheet.append(rawList) # 追加一行
print("正在保存...")
workbook.save(finalResultExcel)为防止IP屏蔽,可以拉大delay值。
原始代码来自于[GitHub](https://github.com/bytegoing/CETMarkQuery)