模拟登录爬取广职院正方教务系统

2 篇文章 0 订阅
1 篇文章 0 订阅

最近突然的想爬取学校的课程表,于是经过几经努力,终于出来的一个小demo,话不多说,马上为大家讲解:先放上代码

import re
import requests
from fake_useragent import UserAgent
from pyquery import PyQuery as pq
from school_api.check_code import CHECK_CODE

class GDSchool(object):
    def __init__(self):
        self.ua=UserAgent()  #用于随机浏览器头
        self.headers={
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Language':'Accept-Language',
            'Host':'61.142.209.20:9090',
            'Accept-Encoding':'gzip, deflate',
            'UserAgent':self.ua.random
                      }
        self.number='*******'#input('请输入学号:')          测试的时候我是直接输入了学号与密码
        self.password='**********'#input('请输入密码:')

    def responseMenu(self,data): #获取菜单链接
        html=pq(data.text)
        mainItems = {}
        menu=html('#headDiv > ul li').items()
        for subItems in menu:
            sub_nextItems = {}
            for nextItems in  subItems('ul li a').items():
                subList = []
                sub_nextItems[nextItems.text()]=nextItems.attr('href')
                subList.append(sub_nextItems)
            mainItems[subItems('.top_link').text()]=subList
        return mainItems

    def resonseImage(self): #用于获取验证码并识别验证码,返回验证码
        try:
            response=self.rssions.get('http://61.142.209.20:9090/CheckCode.aspx',stream=True)
            code=CHECK_CODE.verify(response.content)
            # with open(code+'.gif','wb') as fp:
            #     fp.write(response.content)
            return code
        except Exception as e:
            print(e)

    def responseData(self): #用于获取登录data参数
        try:
            response=requests.get('http://61.142.209.20:9090')
            html=pq(response.text)
            VIEWSTATE=html('#form1 #__VIEWSTATE').attr('value')
            EVENTVALIDATION=html('#form1 #__EVENTVALIDATION').attr('value')
            return {'VIEWSTATE':VIEWSTATE,'EVENTVALIDATION':EVENTVALIDATION}
        except Exception as e:
            print(e)


    def resonsePara(self):  #第一次登录时的初始课表信息
        url='http://61.142.209.20:9090/'+self.menu['信息查询'][0]['个人课表查询']
        referer='http://61.142.209.20:9090/xs_main.aspx?xh={xh}'
        xh=re.findall('xh=(.*?)&xm',url,re.S)[0]
        gnmkdm=re.findall('dm=(.*?)$',url,re.S)[0]
        xm=re.findall(r'xm=(.*?)&gn',url,re.S)[0]
        data={
            'xh':xh,
            'xm':xm,
            'gnmkdm':gnmkdm
        }
        headers={
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Language': 'Accept-Language',
            'Host': '61.142.209.20:9090',
            'Accept-Encoding': 'gzip, deflate',
            'referer':referer.format(xh=xh),   #referer是必要的,没有referer将不能登录到课表页面
            'UserAgent': self.ua.random
        }
        reClss=self.rssions.get(url='http://61.142.209.20:9090/xskbcx.aspx?',params=data,headers=headers)
        return  reClss


    def main(self):  #主程序的调用
        self.rssions=requests.session()
        url='http://61.142.209.20:9090'
        self.rssions.get(url=url)
        url_login='http://61.142.209.20:9090/default2.aspx'
        para=self.responseData()     #返回了登录的参数
        code=self.resonseImage()     #返回验证码
        data={
            '__VIEWSTATE':para['VIEWSTATE'],
            '__EVENTVALIDATION':para['EVENTVALIDATION'],
            'TextBox1':self.number,
            'TextBox2':self.password,
            'TextBox3':code,
            'RadioButtonList1':'%D1%A7%C9%FA',
            'Button1':''
        }
        log_response=self.rssions.post(url=url_login,headers=self.headers,data=data)
        self.menu=self.responseMenu(log_response)         #菜单链接
        self.name=re.findall(r'xm=(.*?)&gn',self.menu['信息查询'][0]['个人课表查询'],re.S)[0]
        self.nameCode=self.name.encode('unicode_escape').decode().replace('\\u','%u')
        # self.parseClassTime(self.menu)
        fisrClss=self.resonsePara()
        self.parseFClss(fisrClss)

    def parseFClss(self, data):
        print(data.text)  #打印课程课程的页面


if __name__ == '__main__':
    gd=GDSchool()
    gd.main()

首先,先来分析一下正方教务,这里分析的是广东职业技术学院的正方教务,要获取课程信息的话,首先第一步是要模拟登录正文:

在这里插入图片描述
创建一个seesion保持会话,这样后面就不需要管cookies了

 self.rssions=requests.session()
        url='http://61.142.209.20:9090'
        self.rssions.get(url=url)

通过输入错误的密码,分析asp可知登录所需的data参数:

       '__VIEWSTATE':para['VIEWSTATE'],
            '__EVENTVALIDATION':para['EVENTVALIDATION'],
            'TextBox1':self.number,
            'TextBox2':self.password,
            'TextBox3':code,
            'RadioButtonList1':'%D1%A7%C9%FA',
            'Button1':''

其中 '__VIEWSTATE‘,‘__EVENTVALIDATION’,这两个参数可在网页中解析出来:

    def responseData(self): #用于获取登录data参数
        try:
            response=requests.get('http://61.142.209.20:9090')
            html=pq(response.text)
            VIEWSTATE=html('#form1 #__VIEWSTATE').attr('value')
            EVENTVALIDATION=html('#form1 #__EVENTVALIDATION').attr('value')
            return {'VIEWSTATE':VIEWSTATE,'EVENTVALIDATION':EVENTVALIDATION}
        except Exception as e:
            print(e)

TextBox1,TextBox2,分别是学号与密码,直接输入即可,RadioButtonList1,这个参数应该是教师端还是学生端的参数,直接复制即可,Button1为空,TextBox3为验证码,通过第三方库直接实现:

    def resonseImage(self): #用于获取验证码并识别验证码,返回验证码
        try:
            response=self.rssions.get('http://61.142.209.20:9090/CheckCode.aspx',stream=True)
            code=CHECK_CODE.verify(response.content)
            # with open(code+'.gif','wb') as fp:
            #     fp.write(response.content)
            return code
        except Exception as e:
            print(e)

参数都获取完成后,通过seesion发起post请求就能跳转到首页页面了:

在这里插入图片描述

后面我是遍历了整个菜单的链接,其实大可不必,可以直接获取课程的链接:

在这里插入图片描述

大家只要把我菜单链接的函数重写成直接获取个课表链接的参数即可:

重写这个函数
  def responseMenu(self,data): #获取菜单链接
        html=pq(data.text)
        mainItems = {}
        menu=html('#headDiv > ul li').items()
        for subItems in menu:
            sub_nextItems = {}
            for nextItems in  subItems('ul li a').items():
                subList = []
                sub_nextItems[nextItems.text()]=nextItems.attr('href')
                subList.append(sub_nextItems)
            mainItems[subItems('.top_link').text()]=subList
        return mainItems

拿到课程链接之后就可以通过seesion访问课表链接,返回response将其解析打印出来即可,这里是没有解析,直接将其html打印出来了

    def resonsePara(self):  #第一次登录时的初始课表信息
        url='http://61.142.209.20:9090/'+self.menu['信息查询'][0]['个人课表查询']
        referer='http://61.142.209.20:9090/xs_main.aspx?xh={xh}'
        xh=re.findall('xh=(.*?)&xm',url,re.S)[0]
        gnmkdm=re.findall('dm=(.*?)$',url,re.S)[0]
        xm=re.findall(r'xm=(.*?)&gn',url,re.S)[0]
        data={
            'xh':xh,
            'xm':xm,
            'gnmkdm':gnmkdm
        }
        headers={
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Language': 'Accept-Language',
            'Host': '61.142.209.20:9090',
            'Accept-Encoding': 'gzip, deflate',
            'referer':referer.format(xh=xh),   #referer是必要的,没有referer将不能登录到课表页面
            'UserAgent': self.ua.random
        }
        reClss=self.rssions.get(url='http://61.142.209.20:9090/xskbcx.aspx?',params=data,headers=headers)
        return  reClss

爬取过程中要注意链接中的编码,有些链接要转换之后才能使用

错误之处还望大家多多指教

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
正方教务网是一个重要的教育管理系统,学生和教师可以在该网站上查询课程信息、成绩、考试安排等。为了方便用户使用,很多人利用编程语言来编写模拟登录程序,实现自动化登录功能。 在Python中,我们可以使用第三方库如requests和BeautifulSoup来实现模拟登录。具体步骤如下: 1. 导入所需的库:requests和BeautifulSoup。 2. 构造登录页面的URL,一般为正方教务网的首页。 3. 使用requests库发送GET请求,获取登录页面的HTML内容。 4. 利用BeautifulSoup库进行页面解析,找到登录表单的所有输入元素的name和value。 5. 通过requests库构造POST请求的表单数据,其中包括用户名和密码等登录信息。 6. 使用requests库发送POST请求,将登录信息提交到正方教务网服务器。 7. 根据服务器返回的响应状态码,判断登录是否成功。 8. 如果登录成功,可以进行后续操作,比如查询课程信息、成绩等。 9. 如果登录失败,可以进行错误处理,比如提示用户重新输入用户名和密码。 需要注意的是,由于正方教务网每个学校的登录页面可能略有差异,我们需要根据具体情况来修改代码中的URL和表单元素的name。 总结来说,通过Python的requests和BeautifulSoup库,我们可以实现模拟登录正方教务网的功能,实现自动化查询课程信息、成绩等操作,提高用户的使用便利性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值