lemoncute 发表于 2018-9-5 23:49

【python】爬取教务系统

本帖最后由 wushaominkk 于 2018-9-6 20:09 编辑

今日闲来无事,试了试爬取学校的教务系统。之前自学了python基础,现在来试一试python的模拟登陆。
好。我们查看一下源代码,或者凭经验可以发现,,这个「成绩」是嵌套在一层有一层frame框架中的。
啊,,好蛋疼啊。。。。。
啊,,好蛋疼啊。。。。。
http://lemoncute.top/build/usr/uploads/2018/09/126775544.png
事实上,,我们可以发现四个页面:
本学期成绩: http://urp/bxqcjcxAction.do
学年成绩:http://urp/gradeLnAllAction.do?type=ln&oper=qbinfo&lnxndm
方案成绩:http://urp/gradeLnAllAction.do?type=ln&oper=fainfo&fajhh=3792
打印成绩:http://urp/reportFiles/student/cj_zwcjd_all.jsp
这个也要看学校的教务系统而定。
http://lemoncute.top/build/usr/uploads/2018/09/3445811646.png
由于学校教务系统没有验证码,所以模拟登陆比较容易..
首先F12查看登陆提交内容
http://lemoncute.top/build/usr/uploads/2018/09/836692483.png
重点就在 From Data里,也就是我们需要 post提交的内容
用到的库主要有
import re
import requests

这里特别注意 需要先get一下主页获取连接的cookie值,在提交数据时加上cookie(session自带),才能正确的提交登录信息

[*]1.模拟登陆

#需要提交的数据
data = {'zjh':'xxx',
      'mm':'xxx'
       }
def login(data):
    #设置请求头 模拟浏览器
    header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
            }#登录时表单提交到的地址(用开发者工具可以看到)
    url = 'http://你学校的教务系统'
    login_url=url+"/loginAction.do"
    session = requests.Session()#使用session保持连接
    resp = session.get(url)#首先get方式获取cookies
    print(session.cookies)
    resp=session.post(login_url,data) #带cookies方式提交
    #print(resp.content.decode('gbk'))#登录成功--打印登录页
    s=resp.content.decode('gbk')
    if s.find("frame")>=0:   #教务系统 大量使用frame框架
      print("登陆成功")
    else:
      print("登录失败")
    return session




[*]2. 查询成绩

我们成功模拟登陆URP系统,接下来查看源代码,发现这个URP系统是一个框架套一个框架。很难找
我们仔细找,最终可以找到某个frame里嵌入的地址,这正是我们需要的,上面列举了几个。

http://lemoncute.top/build/usr/uploads/2018/09/506740308.png
我们获取 本学期成绩。。这里要注意 编码问题,可指定为 网页的默认编码。
def catch(session):
    resp = session.get("http://你学校的教务系统/bxqcjcxAction.do")#本学期课表
    save = resp.content.decode('gbk')
    f=open( 'index.html', "w+")
    f.write(save)
    print("下载完成")
    f.close()

这里我存入了一个 index。html文件里,方便以后处理。
得到一个html、表格

[*]3.数据提取

使用正则表达式提取出我们想要的信息
def deal():
    language=open("index.html", "r").read()
    res = r'<td align="center">(.*?)</td>'
    m = re.findall(res, language, re.S | re.M)
    index=True
    for line in m:
      line = line.strip()
      ifre.match(r'',line,re.M):
            line=""
      if index:
            print(line,end=",")
      else:
            print(line+",")
            index=True
      if line=="学位"or line=="任选" or line=="必修" or line=="选修":
            index=False

07011150,01,数字信号处理,,3.5,学位,90,
07020520,01,传感器原理课程设计,,1,必修,优秀,
07021160,01,数字信号处理课程设计,,1,必修,优秀,
07020530,01,单片机原理及应用,,3.5,必修,68,
07020660,01,电子测量技术,,3.5,必修,73,
07020710,01,高频电子技术,,3.5,必修,76,

用 逗号 隔开方便以后的处理


[*]4..获取到的数据保存为 csv

http://lemoncute.top/build/usr/uploads/2018/09/2658788664.png
csv可以直接用 Excel解析,好了数据已经做成了 表格,接下来就随便你处理了..



源代码   https://www.lanzouj.com/i1thu9g

夸克逃逸 发表于 2019-8-14 12:11

panzhengdong 发表于 2019-8-14 08:33
构建请求头

我的问题不是不能正常进入(不能从正方教务系统进入的原因是我忘记了密码),我的问题是我现在从学校官网进入输入账号密码之后登录看不到formdata。(或者说我理解错了你的“构建请求头”的意思?)

夸克逃逸 发表于 2019-8-13 14:03

楼主请教一个问题。我们学校的正方教务系统的账号密码不能正常进入,于是我只能从学校的主页进入。但是我使用谷歌开发者工具,在输入账号密码点击登录之后,只有一个process请求,里面的formdata只有一个serviceinfo,请问是咋回事儿呢,望不吝赐教谢谢啦。

13169456869 发表于 2018-9-6 00:34

感谢分享

dreamer521 发表于 2018-9-6 01:45

感谢楼主。使用的同款教务系统

icristopher 发表于 2018-9-6 03:27

这个很有意思。

lemoncute 发表于 2018-9-6 06:35

dreamer521 发表于 2018-9-6 01:45
感谢楼主。使用的同款教务系统

学校教务系统没有 验证码,登录就容易很多了。

ALCATEL 发表于 2018-9-6 07:16

还有源码

伤心小王子 发表于 2018-9-6 07:23

支持一下,希望楼主做的更好,加油!

Scavengers 发表于 2018-9-6 07:29

支持一下

夏无道 发表于 2018-9-6 07:34

如果能做这个系统的选课就好了

lhd990608 发表于 2018-9-6 07:44

666感谢楼主
页: [1] 2 3 4 5 6 7
查看完整版本: 【python】爬取教务系统