强智科技·教务网成绩爬取系列文章之爬虫思路

我们学校的教务网是强智科技的,平时必须IE才能打开,而我用Chrome,所以我做了这么一个爬虫工具,方便自己查阅教务网成绩,希望对你有帮助~



用到的python库:re、requests


爬虫思路(xxx代表教务网网址,不便传播)

  1. 创建一个Requests会话对象(所有的爬虫步骤都在该会话下进行)。
1s = requests.Session()
  1. get教务网的登陆页面,返回的头部信息中的cookies信息。
1r = s.get(r'http://xxxxxxxxx/', headers=kdjw_hed)
2cookies = r.headers['Set-Cookie'][0:-12]
  1. 根据获取到cookies信息实时获取当前登录页面的验证码图片信息,并把它的二进制文件信息存储为code.jpg。
1r_verifycode = s.get(r'http://xxxxxxxxx/verifycode.servlet', headers=verifycode_hed)
2with open('code.jpg','wb') as f:
3    f.write(r_verifycode.content)
  1. 请求用户输入验证码,然后把所收到的验证码字符串以及用户输入的学号,密码POST到真正的登录的页面,进而实现模拟登陆。
1r_login = s.post(r'http://xxxxxxxxx/Logon.do?method=logon', headers=post_hed, data=login_data)
  1. 模拟登陆后,先用regex匹配所要获取的成绩数据所在页面的页数,然后再向该url提交查询参数(params),例如:'kksj':开课时间;'PageNum':页码,使用for循环,进而获取到每一页的成绩数据。
1regex = re.compile(r'name = "totalPages" value="(.*?)"')
1#示例:某一页
2r_page = s.get(r'http://xxxxxxxxx/xszqcjglAction.do?method=queryxscj', headers=query_hed, params=page_param, timeout=3)

获取到成绩信息的原始数据之后,我们就可以进行数据的清洗和整理了~


该思路的源代码(代码并不能直接运行)

1#import sys  
2#import io  
3import re  
4import requests  
5#from PIL import Image  
6  
7#改变标准输出的默认编码 8#sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')  
9 
10def get_cookies(): 
11    '从kdjw/的Set-Cookie获取整个会话的cookies' 
12    kdjw_hed = {'Host': 'xxxxxxxxx', 
13        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',} 
14    r = s.get(r'http://xxxxxxxxx/',headers=kdjw_hed, timeout=3) 
15    #print(r.headers) 
16    #获取到cookies 
17    cookies = r.headers['Set-Cookie'][0:-12] 
18    return cookies 
19 
20def get_verifycode(cookies): 
21    '根据所得cookies获取验证码' 
22    verifycode_hed = {'Cookie': cookies, 
23        'Host': 'xxxxxxxxx', 
24        'Referer': 'http://xxxxxxxxx/', 
25        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',} 
26    #验证码获取 
27    r_verifycode = s.get(r'http://xxxxxxxxx/verifycode.servlet', headers=verifycode_hed, timeout=3) 
28 
29    with open('code.jpg','wb') as f: 
30        f.write(r_verifycode.content) 
31    return True 
32 
33#def show_verifycode(): 
34#    '通过Image模块展示验证码图片,并提示用户输入验证码' 
35#    im = Image.open('code.jpg') 
36#    im.show() 
37#    verifycode = input('请输入验证码: ') 
38#    return verifycode 
39 
40def virtual_login(verifycode, cookies, usr, pwd): 
41    '虚拟登陆教务网' 
42    #模拟登陆 
43    login_data = {'useDogCode': '', 
44        'USERNAME': usr, 
45        'PASSWORD': pwd, 
46        'RANDOMCODE': verifycode} 
47    post_hed = {'Cookie': cookies, 
48        'Host': 'xxxxxxxxx', 
49        'Origin': 'http://xxxxxxxxx', 
50        'Referer': 'http://xxxxxxxxx/', 
51        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36', 
52    } 
53    r_login = s.post(r'http://xxxxxxxxx/Logon.do?method=logon', headers=post_hed, data=login_data, timeout=3) 
54    #验证登陆 
55    r_verifylogin = s.get(r'http://xxxxxxxxx/framework/main.jsp', headers=post_hed) 
56    regex = re.compile(r'<title>XXXX大学数字化校园平台-XX科技</title>') 
57    verifylogin = regex.search(r_verifylogin.text) 
58    if verifylogin: 
59        return False 
60    else: 
61        return True 
62 
63def search_and_get_grades_html(cookies, kksj): 
64    '模拟登陆之后,打开成绩查询页面获取并返回成绩源数据' 
65    #成绩查询,针对不止一页成绩数据的情况进行优化 
66    form_data = {'kksj': kksj, 'kcxz': '', 'kcmc': '', 'xsfs': 'qbcj', 'ok':'', } 
67    query_hed = {'Cookie': cookies, 
68        'Host': 'xxxxxxxxx', 
69        'Origin': 'http://xxxxxxxxx/', 
70        'Referer': 'http://xxxxxxxxx/jiaowu/cjgl/xszq/query_xscj.jsp', 
71        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',}
72    r_grade = s.post('http://xxxxxxxxx/xszqcjglAction.do?method=queryxscj', headers=query_hed, data=form_data, timeout=3) 
73    #获取总页数 
74    regex = re.compile(r'name = "totalPages" value="(.*?)"') 
75    totalpages = int(regex.findall(r_grade.text)[-1]) 
76    #按页数获取成绩数据 
77    if totalpages == 1: 
78        print('成功获取第1页成绩数据!!! 共1页.',cookies) 
79        return r_grade.text 
80    else: 
81        html_texts = r_grade.text 
82        print('成功获取第1页成绩数据!!! 共%d页.' % totalpages, cookies) 
83        query_hed.update({'Referer': 'http://xxxxxxxxx/xszqcjglAction.do?method=queryxscj'}) 
84        #print(query_hed) 
85        for pagenum in range(2,totalpages+1): 
86            #巧用params 
87            page_param = {'PageNum':pagenum, 'kksj':kksj} 
88            r_page = s.get(r'http://xxxxxxxxx/xszqcjglAction.do?method=queryxscj', headers=query_hed, params=page_param, timeout=3) 
89            html_texts += r_page.text 
90            print('成功获取第%d页成绩数据!!! 共%d页.' % (pagenum, totalpages), kksj, cookies) 
91        return html_texts 
92 
93def get_code_in_file(): 
94    '创建会话,获取cookies,依此获取并保存验证码图片' 
95    global s, cookies_ 
96    s = requests.Session() 
97    #cookies 
98    cookies_ = get_cookies() 
99    #更新验证码code.jpg
100    get_verifycode(cookies_)
101    return cookies_
102
103def main(verifycode_, cookies_, usr_, pwd_, kksj_):
104    '模拟登陆,验证登陆后获取并返回成绩源数据'
105    orignal_html = ''  #初始化变量orignal_html
106    login = virtual_login(verifycode_, cookies_, usr_, pwd_)
107    if login:
108        orignal_html = search_and_get_grades_html(cookies_, kksj_)
109    #print(orignal_html)110    return orignal_html

经过一番手动测试,发现之前我获取到的仅仅是第一页的成绩数据。对于成绩数据大于一页的同学就显示不了了。
现在,我对之前的代码进行了部分精简和修改,爬虫的正确功能已经实现了,此处应有掌声~
但是,在教务网打不开(大部分情况可能是服务器在未通知的情况下进行维护)的时候,成绩数据是无法获取的。(2018.7.13 22:54, Modified)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容