Python 模拟登陆南邮智慧校园查询成绩

2019/8/24日已经更新,详情看后面分割线处

之前爬取智慧校园在网页登录后把cookies保存下来,放进代码里,可以运行,还以为完事了,挺简单,但是过了一段时间再运行发现,好像出现了cookies会过期的问题,再经过ctrl+U查看源代码,发现里面的这么一段:在这里插入图片描述
里面的值是很有用的
登录界面url:http://ids6.njupt.edu.cn/authserver/login?service=http%3A%2F%2Fmy.njupt.edu.cn%2Findex.do
目前更变为:http://ids6.njupt.edu.cn/authserver/login?service=http%3A%2F%2Fyjs.njupt.edu.cn%2Fepstar%2Fweb%2Fswms%2Fmainframe%2Fhome.jsp
在登录界面中打开审查元素,输入学号和密码后再点击登录
在这里插入图片描述
进入下图页面
在这里插入图片描述
其中Headers中的From Data是发送发post请求时要用的关键信息,而里面的lt值是会改变的,这就是为什么使用一成不变的cookies会失效的原因,这个lt值其实在登录页面的源代码中,随着你每次的访问而变化,因此关键就是找到it值

我们回到登录页面:http://ids6.njupt.edu.cn/authserver/login?service=http%3A%2F%2Fmy.njupt.edu.cn%2Findex.do

目前更变为:http://ids6.njupt.edu.cn/authserver/login?service=http%3A%2F%2Fyjs.njupt.edu.cn%2Fepstar%2Fweb%2Fswms%2Fmainframe%2Fhome.jsp
在该页面的源代码里面的lt值就是我们所需要的。
除了以上工作,我们还需要注意的是,在我们请求登录页面以获取lt值后,如果再用post发送我们构造好的表单,在这个过程中,相当于刷新了一下页面,换句换说,我们先前获得的lt值已经不再是现在的lt值了,所以这个时候我们就要用requests的session方法来保持cookie不变,session方法可以让同一个实例发出的所有请求保持相同的cookie。
参考文章:

https://blog.csdn.net/kelvinmao/article/details/51628649
https://www.cnblogs.com/wzxwhd/p/5966563.html

以下是完整代码:

import requests
from lxml import etree
def getpage(login_url,header,url):
    res_keep=requests.Session()#保持Cookie不变,然后再次访问这个页面
    ex_html=res_keep.get(login_url,headers=header).text
    html=etree.HTML(ex_html)
    value=html.xpath('//div[@class="box"]/form/input/@value')
    postdata={
        'username':'xxxxx',#此处为你的学号
        'password':'xxxxx',#你的密码
        'lt':value[0],#可变的
        'dllt':value[1],
        'execution':value[2],
        '_eventId':value[3],
        'rmShown':value[4]}
    res_post=res_keep.post(login_url,data=postdata,headers=header)#使用构建好的postdata重新登录发送post请求,用之前的res_keep进行post请求
    respond=res_keep.get(url,headers=header).text#获取到成绩页面源代码,用之前的res_keep进行get请求
    return respond

def checkgrade(page):
    html=etree.HTML(page)
    course_name=html.xpath('//td[@class="t_td"]/font[@id="kcmc"]/text()')
    course_grade=html.xpath('//td[@class="t_td"]/font[@id="cj"]/text()')
    pscj=html.xpath('//td[@class="t_td"]/font[@id="pscj"]/text()')
    qmcj=html.xpath('//td[@class="t_td"]/font[@id="qmcj"]/text()')
    k=len(course_name)
    no_grade=[];sum=0;j=0  #sum用来记录成绩的和  #j用来记录成绩已经录入的课程数目
    for i in range(k):
        if course_grade[i]=='成绩未录入':
            no_grade.append(i) #将未录入成绩所对应的i值放入no_grade列表,以便后面展示调用
        else:
            j=j+1
            sum=sum+float(course_grade[i]) #sum是数字,course_grade[i]是字符串,所以把course_grade[i]变成float型
            print('总评:%s'%course_grade[i]+' 期末:%s'%qmcj[i]+'平时:%s'%pscj[i]+'<---'+course_name[i])#打印出成绩已经录入的课程名字以及对应分数
    #以下是计算均分部分
    if j==0:#如果j==0说明成绩都还没录入
        print('所有成绩都还未出')
    else:#如果j!=0说明至少有一门成绩录入了
		print(str(j)+'门均分为:'+'%.2f'%(sum/j)+'\n')
        for each in no_grade:
            print('成绩未录入'+' <--- '+course_name[each])#打印出成绩还未录入的课程名字

if __name__ =='__main__':
    header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0'}
    login_url='http://ids6.njupt.edu.cn/authserver/login?service=http%3A%2F%2Fyjs.njupt.edu.cn%2Fepstar%2Fweb%2Fswms%2Fmainframe%2Fhome.jsp'#登录页面url
    #url是指成绩页面
    url='http://yjs.njupt.edu.cn/epstar/app/template.jsp?mainobj=YJSXT/PYGL/CJGLST/V_PYGL_CJGL_KSCJHZB&tfile=KSCJHZB_CJCX_CD/KSCJHZB_XSCX_CD_BD&filter=V_PYGL_CJGL_KSCJHZB:WID=%275m3b6a53-8l95jp-jhk08lc3-1-jidxxpoh-1i5l%27'
    page=getpage(login_url,header,url)
    if '验证码'in page:
        print('请检查用户名和密码,稍候再试!')
    else:
        checkgrade(page)

菜鸟一枚,自学python没多久,第一次写博客,水平有限,还请大神指教,轻喷

**

—————2019/8/24日更新———分割线——————————

**

官网的登录地址有变化了,然后代码稍微变化了几个地方

  1. 一个是login_url变成了 http://rzfw.njupt.edu.cn/cas/login?service=http%3A%2F%2Fyjs.njupt.edu.cn%2Fepstar%2Fweb%2Fswms%2Fmainframe%2Fhome.jsp

  2. 因为postdata就是根据login_url页面去获取的,因此post请求所需的postdata变化了
    原来的postdata为:
    postdata={
    ‘username’:‘xxxxx’,#此处为你的学号
    ‘password’:‘xxxxx’,#你的密码
    ‘lt’:value[0],#可变的
    ‘dllt’:value[1],
    ‘execution’:value[2],
    ‘_eventId’:value[3],
    ‘rmShown’:value[4]}
    现在变成:
    postdata={
    ‘username’:‘xxxxxx’,#此处为你的学号
    ‘password’:‘xxxxxx’,#你的密码
    ‘authcode’:’’,
    ‘execution’:value[0],
    ‘_eventId’:‘submit’}
    这里我们要获取的 ‘execution’的值再login_url页面查看源代码可以找到:
    在这里插入图片描述
    由于它是唯一的,所以直接在input标签下的属性name="execution"的就可以找到
    因此我们的变成了value=html.xpath(’//input[@name=“execution”]/@value’)

  3. 还有就是之前默认是utf-8编码格式,现在是ISO-8859-1,因此要加上respond.encoding=“utf-8”,防止中文乱码.
    更新后代码如下:

import requests
from lxml import etree
def getpage(login_url,header,url):
    res_keep=requests.Session()#保持Cookie不变,然后再次访问这个页面
    ex_html=res_keep.get(login_url,headers=header).text
    html=etree.HTML(ex_html)
    value=html.xpath('//input[@name="execution"]/@value')
    postdata={
        'username':'xxxxx',#此处为你的学号
        'password':'xxxxx',#你的密码
        'authcode':'',
        'execution':value[0],
        '_eventId':'submit'}
    res_post=res_keep.post(login_url,data=postdata,headers=header)#使用构建好的postdata重新登录发送post请求,用之前的res_keep进行post请求
    respond=res_keep.get(url,headers=header)#获取到成绩页面源代码,用之前的res_keep进行get请求
    respond.encoding="utf-8"#要申明编码格式,不然中文会乱码
    return respond.text

def checkgrade(page):
    html=etree.HTML(page)
    course_name=html.xpath('//td[@class="t_td"]/font[@id="kcmc"]/text()')
    course_grade=html.xpath('//td[@class="t_td"]/font[@id="cj"]/text()')
    pscj=html.xpath('//td[@class="t_td"]/font[@id="pscj"]/text()')
    qmcj=html.xpath('//td[@class="t_td"]/font[@id="qmcj"]/text()')
    k=len(course_name)
    no_grade=[];sum=0;j=0  #sum用来记录成绩的和  #j用来记录成绩已经录入的课程数目
    for i in range(k):
        if course_grade[i]=='成绩未录入':
            no_grade.append(i) #将未录入成绩所对应的i值放入no_grade列表,以便后面展示调用
        else:
            j=j+1
            sum=sum+float(course_grade[i]) #sum是数字,course_grade[i]是字符串,所以把course_grade[i]变成float型
            print('总评:%s'%course_grade[i]+' 期末:%s'%qmcj[i]+'平时:%s'%pscj[i]+'<---'+course_name[i])#打印出成绩已经录入的课程名字以及对应分数
    #以下是计算均分部分
    if j==0:#如果j==0说明成绩都还没录入
        print('所有成绩都还未出')
    else:#如果j!=0说明至少有一门成绩录入了
        print(str(j)+'门均分为:'+'%.2f'%(sum/j)+'\n')#+'\n'表示除了打印前面的内容还会换行打印一行空白
        for each in no_grade:
            print('成绩未录入'+' <--- '+course_name[each])#打印出成绩还未录入的课程名字

if __name__ == '__main__':
    header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0'}
    login_url='http://rzfw.njupt.edu.cn/cas/login?service=http%3A%2F%2Fyjs.njupt.edu.cn%2Fepstar%2Fweb%2Fswms%2Fmainframe%2Fhome.jsp'#登录页面url
    #url是指成绩页面
    url='http://yjs.njupt.edu.cn/epstar/app/template.jsp?mainobj=YJSXT/PYGL/CJGLST/V_PYGL_CJGL_KSCJHZB&tfile=KSCJHZB_CJCX_CD/KSCJHZB_XSCX_CD_BD&filter=V_PYGL_CJGL_KSCJHZB:WID=%275m3b6a53-8l95jp-jhk08lc3-1-jidxxpoh-1i5l%27'
    page=getpage(login_url,header,url)
    if '验证码'in page:
        print('请检查用户名和密码,稍候再试!')
    else:
        checkgrade(page)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不啻逍遥然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值