记录一次关于校园统一认证平台接口的探索

1. 引言

在学习网络爬虫时,很多人都会选择从自己学校的教务平台入手。本文将详细介绍如何使用 Python 的 requests 库和 execjs 库模拟登录校园统一认证平台,并获取用户信息的过程。通过本文,你将了解如何分析和处理登录页面,提取必要的参数,加密密码,并最终完成登录操作。

2. 环境准备

首先,我们需要安装必要的 Python 库,包括requestsexecjslogurulxml。你可以通过以下命令安装它们:

pip install requests execjs loguru lxml

3. 代码实现

3.1 导入所需库

import time
import execjs
import requests
from loguru import logger
from lxml import etree

这些库分别用于处理时间、执行 JavaScript 代码、发送 HTTP 请求、记录日志以及解析 HTML 文档。

3.2 配置会话和日志

session = requests.session()

# 配置日志记录
logger.add("list.log", rotation="10 MB", retention="10 days", level="INFO")

这里,我们创建了一个会话对象session,并配置了日志记录,日志文件会自动滚动并保留 10 天的记录。

3.3 定义常量和用户信息

# 用户账户和密码
USER_ACCOUNT = ""
USER_PASSWORD = ""

# 常量:域名, 请根据实际情况修改
AUTH_SERVER_DOMAIN = "http://authserver.xxxxxx.edu.cn"
EHALL_DOMAIN = "http://ehall.xxxxxx.edu.cn"

在这里,我们定义了用户账户和密码,以及认证服务器和校园平台的域名。

3.4 获取登录页面

def get_login_page():
    """
    发送GET请求获取登录页面
    """
    response = session.get(
        f"{AUTH_SERVER_DOMAIN}/authserver/login?service={EHALL_DOMAIN}%2Flogin%3Fservice%3D{EHALL_DOMAIN}%2Fywtb-portal%2Fofficial%2Findex.html"
    )
    return response

通过发送 GET 请求,我们可以获取登录页面的 HTML 内容。

3.5 提取登录页面参数

def extract_parameters(tree):
    """
    提取加密盐、lt和execution参数
    """
    pwdDefaultEncryptSalt = tree.xpath('//input[@id="pwdDefaultEncryptSalt"]/@value')[0]
    lt = tree.xpath('//input[@name="lt"]/@value')[0]
    execution = tree.xpath('//input[@name="execution"]/@value')[0]
    logger.info(f"pwdDefaultEncryptSalt: {pwdDefaultEncryptSalt}, lt: {lt}, execution: {execution}")
    return pwdDefaultEncryptSalt, lt, execution

使用lxml库,我们可以解析登录页面的 HTML 内容,并提取出加密盐pwdDefaultEncryptSaltltexecution等重要参数。

3.6 获取加密后的密码

def get_encrypted_password(password, salt):
    """
    获取加密后的密码
    """
    response = session.get(
        f"{AUTH_SERVER_DOMAIN}/authserver/custom/js/encrypt.js",
        allow_redirects=False,
    )
    js_code = response.text
    js_res = execjs.compile(js_code)
    encrypted_password = js_res.call("_ep", password, salt)
    logger.info(f"加密后的密码: {encrypted_password}")
    return encrypted_password

通过请求获取加密所需的 JavaScript 代码,并使用execjs库执行该代码以加密密码。

3.7 发送登录请求

def login(username, encrypted_password, lt, execution):
    """
    发送POST请求进行登录
    """
    headers = {
        "Origin": AUTH_SERVER_DOMAIN,
        "Proxy-Connection": "keep-alive",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
    }
    params = {
        "service": f"{EHALL_DOMAIN}/login?service={EHALL_DOMAIN}/ywtb-portal/official/index.html",
    }
    data = {
        "username": username,
        "password": encrypted_password,
        "lt": lt,
        "dllt": "userNamePasswordLogin",
        "execution": execution,
        "_eventId": "submit",
        "rmShown": "1",
    }
    response = session.post(
        f"{AUTH_SERVER_DOMAIN}/authserver/login",
        params=params,
        headers=headers,
        data=data,
        verify=False,
        allow_redirects=True,
    )
    logger.info(f"登录后的cookie: {session.cookies.get_dict()}")
    return response

通过发送 POST 请求,我们将加密后的密码以及其他必要参数发送到服务器以完成登录操作。

3.8 获取用户信息

def get_user_info():
    """
    发送GET请求获取用户信息
    """
    timestamp = int(time.time() * 1000)
    response = session.get(
        f"{EHALL_DOMAIN}/jsonp/ywtb/info/getUserInfoAndSchoolInfo?_={timestamp}"
    )
    logger.info(f"用户信息响应: {response.text}")
    return response.text

登录成功后,我们可以通过发送 GET 请求获取用户的详细信息。

3.9 主函数

def main():
    login_page_response = get_login_page()
    tree = etree.HTML(login_page_response.text)
    pwdDefaultEncryptSalt, lt, execution = extract_parameters(tree)
    encrypted_password = get_encrypted_password(USER_PASSWORD, pwdDefaultEncryptSalt)
    login(USER_ACCOUNT, encrypted_password, lt, execution)
    get_user_info()

if __name__ == "__main__":
    main()

主函数依次调用上述步骤中的函数,完成整个登录和获取用户信息的过程。

4. 总结

通过本文的介绍,你应该已经了解了如何使用 Python 模拟登录校园统一认证平台的过程。具体步骤包括获取登录页面、提取必要参数、加密密码、发送登录请求以及获取用户信息。希望这篇文章对你学习网络爬虫有所帮助。