朋友最近遇上选课困难,手速慢,总是抢不到心仪的课程,我目前正好找不到爬虫项目练手,于是写了个面向复旦选课系统的抢课小软件帮助朋友抢课
首先需要这些模块:
import requests
import re
import time
import schedule
第一步需要做的是通过身份认证并爬取csrf-token,在选课网站登陆后复制cookies到代码中,这是服务器识别你身份的方式,接着网站会通过生成csrf-token并将其包含在选课请求中来进一步保护信息安全;csrf-token这是网站的一道保护措施,网站根据你提交的cookie信息生成一段随机的csrf-token码,你需要将其爬取并应用到后续的请求中。
class csrfscrapy():
def csrf_req(self):
cookies = {
'_WEU': '********',
'route': '***********',
'JSESSIONID': '***********',
'XK_TOKEN': '****************',
}#cookie需替换,根据自己登陆后找到的cookie进行替换
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,en-GB;q=0.6',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Referer': 'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/*default/index.do',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.46',
}
res = requests.get(
'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkHome/gotoChooseCourse.do',
cookies=cookies,
headers=headers,
verify=False,
)
return res
def pares_csrf(self, res):
csrf=re.findall('csrfToken\W+value=\W+([a-z0-9]+)\W', res.text)
csrfstr=csrf[0]
print(csrfstr)
return csrfstr#从html中找到csrftoken
def run(self):
responce=self.csrf_req()
csrfstr=str(self.pares_csrf(responce))
return csrfstr
之后要解决的就是提交选课请求,注意在request.post中有个参数param(dict类型),这是时间13位时间戳,需要整合到url里一起提交;另外一个参数是data(dict类型),里面包含csrf-token和选课信息bjdm,lx,bqmc和身份认证csrfToken。其中bjdm是课程代码,lx是课程类型(数字,专业外语对应7,其他选修课10,公共选修课9),bqmc是课程所在的分类(如专业外语,其他选修课,公共选修课等),lx和bqmc钥匙可以通过自己要选的课程所在的门类进行填写,比如要选的xxx课程在公共选修课,那么'lx': '9', 'bqmc': '公共选修课’。bjdm钥匙需要在浏览器开发者模式中寻找对应的代码,后续详细说明。csrfToken钥匙则是上个部分爬取的结果。
class courceburglar():
def __init__(self, csrf):
self.csrf=csrf
def get_millisecond():
millis = int(round(time.time() * 1000))
return millis
def cource_req(self):
cookies = {
'_WEU': '********',
'route': '***********',
'JSESSIONID': '***********',
'XK_TOKEN': '****************',
}#cookie需替换,根据自己登陆后找到的cookie进行替换
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,en-GB;q=0.6',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Origin': 'http://yjsxk.fudan.sh.cn',
'Referer': 'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkHome/gotoChooseCourse.do',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.46',
'X-Requested-With': 'XMLHttpRequest',
}
timestramp = courceburglar.get_millisecond()
print(timestramp)
params = {
'_': timestramp,
}
data = {
'bjdm': '************',
'lx': '7',
'bqmc': '专业外语',
'csrfToken': self.csrf,
}
response = requests.post(
'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkCourse/choiceCourse.do',
params=params,
cookies=cookies,
headers=headers,
data=data,
verify=False,
)
print(response.status_code)
def run(self):
responce=self.cource_req()
如何寻找cookie:首先登陆自己选课账号,进入选课界面,f12打开开发者界面中的网络(或者network)选项卡,刷新你的浏览器,在你的开发者界面会有如下的状态,打开任意一个形如r'\w+do\?_=\d+'命名的文件的请求头(或者headers)选项卡,在request headers中包含了cookie信息,稍微加工改成dict类型,替换掉两部分代码中cookies部分.
如何寻找课程代码:清空你的开发者界面,将你的选课类别调整到你需要选的类型中,比如你要选公共选修课的课程,你将浏览器中的选项点击到公共选修课,与此同时,在开发者界面会出现响应的文件,打开形如'loadxxxxxcourceinfo.do?_=xxxxxx'文件,打开preview的选项卡,在众多检索出的课程中找到你要的课程的BJDM,并替换掉data参数里面的bjdm。
代码最后就是时间部分:通过schedule模块控制选课请求发送时间。选课系统一般是下午一点开放。
if __name__=='__main__':
def job(cs):
crsreq = courceburglar(cs)
crsreq.run()
csrf=csrfscrapy()
csrftoken=csrf.run()
#schedule.every(5).to(10).minutes.do(job, csrftoken) #5-10分钟随机做一次
schedule.every().day.at("13:00").do(job, csrftoken)
while True:
schedule.run_pending()
time.sleep(1)
具体参考这位大佬的内容:(10条消息) Python3学习(八):使用schedule模块定时执行任务_猪笨是念来过倒的博客-CSDN博客_schedule.run_pending()
整合起来全代码如下:文章来源:https://www.toymoban.com/news/detail-689444.html
import requests
import re
import time
import schedule
class csrfscrapy():
def csrf_req(self):
cookies = {
'_WEU': '********',
'route': '***********',
'JSESSIONID': '***********',
'XK_TOKEN': '****************',
}#cookie需替换,根据自己登陆后找到的cookie进行替换
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,en-GB;q=0.6',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Referer': 'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/*default/index.do',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.46',
}
res = requests.get(
'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkHome/gotoChooseCourse.do',
cookies=cookies,
headers=headers,
verify=False,
)
return res
def pares_csrf(self, res):
csrf=re.findall('csrfToken\W+value=\W+([a-z0-9]+)\W', res.text)
csrfstr=csrf[0]
print(csrfstr)
return csrfstr#从html中找到csrftoken
def run(self):
responce=self.csrf_req()
csrfstr=str(self.pares_csrf(responce))
return csrfstr
class courceburglar():
def __init__(self, csrf):
self.csrf=csrf
def get_millisecond():
millis = int(round(time.time() * 1000))
return millis
def cource_req(self):
cookies = {
'_WEU': '********',
'route': '***********',
'JSESSIONID': '***********',
'XK_TOKEN': '****************',
}#cookie需替换,根据自己登陆后找到的cookie进行替换
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,en-GB;q=0.6',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Origin': 'http://yjsxk.fudan.sh.cn',
'Referer': 'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkHome/gotoChooseCourse.do',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.46',
'X-Requested-With': 'XMLHttpRequest',
}
timestramp = courceburglar.get_millisecond()
print(timestramp)
params = {
'_': timestramp,
}
data = {
'bjdm': '************',
'lx': '7',
'bqmc': '专业外语',
'csrfToken': self.csrf,
}
response = requests.post(
'http://yjsxk.fudan.sh.cn/yjsxkapp/sys/xsxkappfudan/xsxkCourse/choiceCourse.do',
params=params,
cookies=cookies,
headers=headers,
data=data,
verify=False,
)
print(response.status_code)
def run(self):
responce=self.cource_req()
if __name__=='__main__':
def job(cs):
crsreq = courceburglar(cs)
crsreq.run()
csrf=csrfscrapy()
csrftoken=csrf.run()
#schedule.every(5).to(10).minutes.do(job, csrftoken) #5-10分钟随机做一次
schedule.every().day.at("13:00").do(job, csrftoken)
while True:
schedule.run_pending()
time.sleep(1)
后续改进可以写一个可以自动生成需要的选课信息并将信息放进队列的模块,以及多线程同时发送选课请求的模块。文章来源地址https://www.toymoban.com/news/detail-689444.html
到了这里,关于python实现复旦大学选课系统自动抢课神器抢课软件Courcegoblin抢课软件ver 1.0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!