Python中如何编写正方系统的SDK

写了一个正方教务系统 SDK,最近想优化一下多校兼容问题。

请各位大佬能登陆的,帮忙测试下能否正常使用,并提些建议。

正方教务系统 SDK Github 地址: https://github.com/dairoot/school-api

也可以在测试地址测试: http://server.dairoot.cn (勿压)

目前仅支持旧版教务系统,新版没有账号测试。

请无法使用 SDK 的,可私聊我发送:外网地址+账号密码,有空我会做下兼容。


Python中如何编写正方系统的SDK

3 回复

我理解你想为正方教务系统这类内部系统写个SDK。这活儿我干过,核心就是逆向分析它的接口。

首先你得用浏览器开发者工具抓包,看看它的请求参数、headers、cookie结构。通常这类系统会有一些固定的验证参数,比如__VIEWSTATE__EVENTVALIDATION这些ASP.NET的玩意儿。

给你个基础框架:

import requests
from typing import Dict, Any
import re

class ZhengfangClient:
    def __init__(self, base_url: str):
        self.session = requests.Session()
        self.base_url = base_url.rstrip('/')
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
    
    def _get_hidden_fields(self, html: str) -> Dict[str, str]:
        """提取ASP.NET的隐藏字段"""
        patterns = {
            '__VIEWSTATE': r'id="__VIEWSTATE" value="([^"]+)"',
            '__VIEWSTATEGENERATOR': r'id="__VIEWSTATEGENERATOR" value="([^"]+)"',
            '__EVENTVALIDATION': r'id="__EVENTVALIDATION" value="([^"]+)"'
        }
        result = {}
        for key, pattern in patterns.items():
            match = re.search(pattern, html)
            if match:
                result[key] = match.group(1)
        return result
    
    def login(self, username: str, password: str) -> bool:
        """模拟登录流程"""
        # 1. 先获取登录页,提取隐藏字段
        login_url = f"{self.base_url}/default2.aspx"
        resp = self.session.get(login_url)
        hidden_fields = self._get_hidden_fields(resp.text)
        
        # 2. 构造登录数据
        login_data = {
            **hidden_fields,
            'txtUserName': username,
            'TextBox2': password,
            'RadioButtonList1': '学生',  # 或'教师'
            'Button1': '',
            'lbLanguage': ''
        }
        
        # 3. 提交登录
        post_resp = self.session.post(login_url, data=login_data)
        return '请选择' in post_resp.text  # 根据实际成功标志判断
    
    def get_schedule(self, year: str, term: str) -> Dict[str, Any]:
        """获取课表"""
        # 先跳转到课表页面
        schedule_url = f"{self.base_url}/xskbcx.aspx"
        self.session.get(schedule_url)
        
        # 构造查询参数
        data = {
            '__EVENTTARGET': 'xnd',
            '__EVENTARGUMENT': '',
            'xnd': year,
            'xqd': term
        }
        
        resp = self.session.post(schedule_url, data=data)
        # 这里解析课表HTML,返回结构化数据
        return self._parse_schedule(resp.text)
    
    def _parse_schedule(self, html: str) -> Dict[str, Any]:
        """解析课表HTML,具体实现根据页面结构来"""
        # 用BeautifulSoup或正则解析
        pass

# 使用示例
if __name__ == "__main__":
    client = ZhengfangClient("http://jwgl.xxx.edu.cn")
    if client.login("学号", "密码"):
        schedule = client.get_schedule("2023-2024", "1")
        print(schedule)

关键点:

  1. 保持session,cookie会自动管理
  2. 每次请求前可能需要先获取页面提取隐藏字段
  3. 注意编码问题,这类系统常用gb2312/gbk
  4. 不同学校可能有些自定义参数,需要具体分析

建议:先完整抓取几个关键流程的请求,再逐个实现。


正方这个系统根据学校的不同,在前端的数据的组织方式也可能不同,比较头疼的就是很难通用起来

最近就想处理这个问题,你可以正常使用 SDK 不?

回到顶部