使用python+requests+re完成每日打卡
1、登录
-
浏览器登录,抓包并分析
https://ssp.scnu.edu.cn/login.aspx(登录网址)
这是登陆时需要提交的数据
需要自己填的,log_username (用户名) log_password(密码)这里学校没有加密,所以很容易
-
比较分析
登陆后,浏览器自动跳转到另一个页面https://ssp.scnu.edu.cn/default.aspx
登录后的页面
与未登录的页面比较
登录的页面多了打卡的链接,而经过后面博主多次注销登录比较打卡的链接
https://ssp.scnu.edu.cn/opt_rc_jkdk.aspx?key=SFZn8bJZB7CyjPe9&fid=55
https://ssp.scnu.edu.cn/opt_rc_jkdk.aspx?key=jWoei0QLiWLLOFfn&fid=55
https://ssp.scnu.edu.cn/opt_rc_jkdk.aspx?key=HD06uu9MuslIOp2P&fid=55
发现链接中的 key在不断变化,因此推断出这个就是证明我们“身份”的东西
检索发现这个链接就在登录后跳转的页面之中
2、获取需要的url
-
为了获取上一步分析得出的url,这里使用requests.Session()来访问跳转后的网址,可以在登录后保持会话,达到“证明身份”的目的
session = requests.Session()
-
将网页源代码爬取下来,利用re库获取地址,或者可以使用BeautifulSoup和xml等其他的解析库
# 下载下来的部分源代码 li><a href="\opt_xx_myapps.aspx?key=N4WtHPTaZwInQYqK&fid=55">疫情防控</a> <ul> <li class="bg0"><a href="opt_rc_jkdk.aspx?key=N4WtHPTaZwInQYqK&fid=55">健康打卡</a></li> <li class="bg1"><a href="opt_rc_jkdkcx.aspx?key=N4WtHPTaZwInQYqK&fid=55">近日打卡查询</a></li> # 需要匹配的目标字符串 opt_rc_jkdk.aspx?key=N4WtHPTaZwInQYqK&fid=55 # 利用re匹配 target_url_1 = re.findall("<.*?href=\"(.*?)\">健康打卡.*?",html)[0] # 这样 target_url_1 的值就是 opt_rc_jkdk.aspx?key=N4WtHPTaZwInQYqK&fid=55
可以看到保持会话使我们可以拿到登录后才能看到的页面信息
-
拼接url
对比
https://ssp.scnu.edu.cn/opt_rc_jkdk.aspx?key=N4WtHPTaZwInQYqK&fid=55
opt_rc_jkdk.aspx?key=N4WtHPTaZwInQYqK&fid=55host_url = "https://ssp.scnu.edu.cn/" target_url_1 = re.findall("<.*?href=\"(.*?)\">健康打卡.*?",html)[0] url = host_url+target_url_1 # url的值就是最终需要我们提交信息的url
3、提交信息
-
浏览器提交后抓包分析
发现有一堆的东西,直接做成字典就好了,一些需要个人改动的等之后可以用户输入
4、最终代码
import requests # 用于网络请求
import re # 用于解析信息
import os
# 登录时需要提交的信息,log_username log_password 用户输入
login_data ={
"log_username":"",
"log_password":"",
"__EVENTARGUMENT":"",
"__EVENTTARGET":"logon",
"__VIEWSTATE":"/wEPDwUKMTYyMDg3MzEwOA9kFgICAw9kFgQCCQ8PFgIeBFRleHQFOkZ4IOmrmOagoeWtpueUn+e7vOWQiOacjeWKoeW5s+WPsCDlrabnlJ/lt6XkvZznrqHnkIbns7vnu59kZAILDw8WAh8ABVPljZXkvY3ogZTns7vmlrnlvI865bm/5bee5biC5aSp5rKz5Yy65Y2O5Y2X5biI6IyD5aSn5a2m5a2m55Sf5bel5L2c5aSEfOeglOeptueUn+mZomRkZKFnHvVaV81qDojK7N65tZUnV6x/GBGk1yWHcKuktbUf",
"__VIEWSTATEGENERATOR":"C2EE9AB",
"__EVENTVALIDATION":"/wEdAATSYruQs+D6SrVLjTCpxZHV1kNwsRYEDqnEZGvD/d7NHmTWfBqM7WrvRN2Hp35y65arCB7eRXhUFaYy1hE/nWj6yIQ54P9oI0KOTBNfahXd3vQ3YHjvczXF34SWDVFZlnY="
}
# 打卡时需要提交的信息
# 信息已处理
daka_data={
"__EVENTTARGET":"",
"__EVENTARGUMENT":"",
"__LASTFOCUS":"",
"__VIEWSTATE":"略",
"ctl00$cph_right$e_location": "广东省广州市天河区", # 所在地区
"ctl00$cph_right$e_health$0": "无不适", # 健康状况
"ctl00$cph_right$e_temp": 36.5, # 温度
"ctl00$cph_right$e_describe":"",
"ctl00$cph_right$e_submit": "提交保存",
"__VIEWSTATEGENERATOR": "DC47EEF4",
"__EVENTVALIDATION": "略"
}
# 请求头
header = {
"User-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36",
"Host":"ssp.scnu.edu.cn",
"Origin":"https://ssp.scnu.edu.cn",
"Referer":"https://ssp.scnu.edu.cn/login.aspx",
}
# 用户输入
def input_info():
# 通过判断数据文件是否存在来判断是否首次输入
if not os.path.exists("data.txt"):
user_id = input("用户名").strip()
password = input("密码").strip()
city = input("所在地区/城市").strip()
temperature = input("温度").strip()
with open("data.txt","w") as f:
f.write(user_id+'\n')
f.write(password+'\n')
f.write(city+'\n')
f.write(temperature)
# 载入信息,将login_data 和 daka_data 的信息更新
def load_info():
with open("data.txt","r") as f:
login_data['log_username'] = f.readline().strip()
login_data['log_password'] = f.readline().strip()
daka_data['ctl00$cph_right$e_location'] = f.readline()
daka_data['ctl00$cph_right$e_temp'] = f.readline()
if __name__ == '__main__':
input_info()
load_info()
host_url = "https://ssp.scnu.edu.cn/"
login_url = "https://ssp.scnu.edu.cn/login.aspx"
session = requests.Session()
session.post(login_url, headers=header, data=login_data, allow_redirects=False)
navigation_url = "https://ssp.scnu.edu.cn/default.aspx"
html = session.get(navigation_url,headers=header).text
target_url_1 = re.findall("<.*?href=\"(.*?)\">健康打卡.*?",html)[0]
url = host_url+target_url_1
session.post(url,headers=header,data=daka_data)