课程表爬虫-已弃坑

课程表爬虫-已弃坑

十月 29, 2020

目录

  1. 总体思路
  2. 网站分析
    1. 登录web系统
    2. 登录教务系统
    3. 获取课表
  3. 开始写代码

1.总体思路

由于查合工大课表需要连接校园网,要实现随时随地爬取课表需要借助学校提供的web***系统。

因此这个爬虫需要两次模拟登录。

第一次是登录web***

web1

第二次是通过web***打开教务系统学生端

web2

2.网站分析

登录web系统

首先用浏览器抓包

s1

do-login是一个post请求,data段很简单,用户名和密码都没有加密,但在此之前需要先获取一个captcha_id,直接请求就行了

后面的info是一个get请求,很明显用于获取信息,禁止JavaScript再打开网页,果然,这个网页是JavaScript动态加载的,info就是用于获取信息,还是不放心?再翻一翻JavaScript,很容易就找到了这个

s2

这下没错了,由于教务系统网址每次都不一样,我们想要通过web***打开它只能通过发送一个叫

1
info?_=xxxxxxxx

的get请求获取网址,等于号后面一眼就能看出来是时间戳

登录教务系统

由于web***系统暂时抽风,先连校园网测试

依然先抓包

j1

这就有点意思了,先get了一个login-salt,再post登录用的login,而且login的数据段的密码加密了!

j2

只能调试JavaScript了。。。

经过一番寻找,终于在

j3

找到了加密方式:先get一个”盐“,连到密码前面,再用SHA1算法加密

其实也不算复复杂,毕竟python自带所有hash算法(在hashlib)里,就算没有,也可以把Google的sha1.js复制过来用python调用

获取课表

抓包抓包~~~

发现两个特别的请求:

get1

get

第一个用于获取加载网页的js,第二个是json信息

我们只需要那个json信息,直接分析并打开网址即可

打开网页,抓包

get3

很简单,看来上面那个网页不用请求,直接获取这个get-data即可,参数就是时间

至此,分析完成

3.开始写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# -*- coding:utf-8 -*-
import requests
from lxml import html
import time
import hashlib

normal_headers = {
r"User-Agent": r"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
r"Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.56 "
}
VPN1_headers = {
r"Accept": r'*/*',
r"Accept-Encoding": r"gzip, deflate, br",
r"Content-Type": r"application/x-www-form-urlencoded; charset=UTF-8",
r"User-Agent": r"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
r"Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.56 ",
r"Cookie": r"show_vpn=1; wengine_vpn_ticketwebvpn_hfut_edu_cn=783a9268eeff4127; remember_token=",
r"Host": r"webvpn.hfut.edu.cn",
r"Origin": r"https://webvpn.hfut.edu.cn",
r"Referer": r"https://webvpn.hfut.edu.cn/login",
r"Sec-Fetch-Dest": r"empty",
r"Sec-Fetch-Mode": r"cors",
r"Sec-Fetch-Site": r"same-origin",
r"X-Requested-With": r"XMLHttpRequest"
}
VPN2_headers = {
r"Accept": r"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,"
r"application/signed-exchange;v=b3;q=0.9",
r"Accept-Encoding": r"gzip, deflate, br",
r"User-Agent": r"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
r"Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.56 ",
r"Cookie": r"show_vpn=1; wengine_vpn_ticketwebvpn_hfut_edu_cn=783a9268eeff4127; remember_token=",
r"Host": r"webvpn.hfut.edu.cn",
r"Referer": r"https://webvpn.hfut.edu.cn/login",
r"Sec-Fetch-Dest": r"document",
r"Sec-Fetch-Mode": r"navigate",
r"Sec-Fetch-Site": r"same-origin",
r"Sec-Fetch-User": r"?1",
r"Upgrade-Insecure-Requests": "1"
}
VPN3_headers = {
r"Accept": r'application/json, text/javascript, */*; q=0.01',
r"Accept-Encoding": r"gzip, deflate, br",
r"User-Agent": r"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
r"Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.56 ",
r"Cookie": r"show_vpn=1; wengine_vpn_ticketwebvpn_hfut_edu_cn=783a9268eeff4127; remember_token=",
r"Host": r"webvpn.hfut.edu.cn",
r"Referer": r"https://webvpn.hfut.edu.cn/",
r"Sec-Fetch-Dest": r"empty",
r"Sec-Fetch-Mode": r"cors",
r"Sec-Fetch-Site": r"same-origin",
r"X-Requested-With": r"XMLHttpRequest"
}
VPN_url = r'https://webvpn.hfut.edu.cn/'


def get_captcha_id(page):
xpath = r'//*[@id="captcha-wrap"]/div/div/input/@value'
page.encoding = page.apparent_encoding
selector = html.fromstring(page.text)
return selector.xpath(xpath)[0]


VPN_session = requests.Session()
data = {
r'auth_type': r'local',
r'username': r'填用户名',
r'sms_code': r'',
r'password': r'填密码',
r'captcha': r'',
r'needCaptcha': r'false',
r'captcha_id': get_captcha_id(VPN_session.get(r'https://webvpn.hfut.edu.cn/login', headers=normal_headers))
}

res0 = VPN_session.post(VPN_url + r'do-login', headers=VPN1_headers, data=data)
res1 = VPN_session.get(VPN_url, headers=VPN2_headers)
res2 = VPN_session.get(VPN_url + r'user/info?_=' + str(int(time.time() * 1000)), headers=VPN3_headers)
print(res1)

已弃坑

由于需求改变,现已经改用node.js实现,并已经完成绝大部分。