自动登录上海大学校园

项目地址:Github仓库

使用 Python 和 Selenium 编写的自动化脚本,用于自动登录校园网认证系统。

demo 里使用了 Chrome 浏览器与驱动,如否访问外网有困难可以尝试改为使用 Edge 浏览器相关套件,效果应该一样。

示例代码:

python 复制代码
import logging
import shutil
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time
import subprocess
import traceback

class CampusNetworkLogin:
    def __init__(self) -> None:
        logging.info("启动 Selenium")

        # 禁用系统代理,防止干扰本地驱动连接
        os.environ['no_proxy'] = '*'
        if 'http_proxy' in os.environ: del os.environ['http_proxy']
        if 'https_proxy' in os.environ: del os.environ['https_proxy']

        # 设置 Chrome 选项
        chrome_options = webdriver.ChromeOptions()
        # 指定下载的 chrome.exe 路径
        chrome_options.binary_location = r"D:\XunLei\chrome-win64\chrome.exe"
        # chrome_options.add_argument("--headless") # 重新开启无头模式
        chrome_options.add_argument("--no-sandbox")
        chrome_options.add_argument("--disable-gpu")
        chrome_options.add_argument("--disable-dev-shm-usage")
        # 忽略证书错误和安全警告
        chrome_options.add_argument("--ignore-certificate-errors")
        chrome_options.add_argument("--ignore-ssl-errors")
        chrome_options.add_argument("--allow-running-insecure-content")
        chrome_options.add_argument("--disable-web-security")
        chrome_options.add_argument("--test-type")
        # 允许不安全证书 (Seleinum 4 标准写法)
        chrome_options.set_capability("acceptInsecureCerts", True)
        # 强制将该站点视为安全站点,防止弹出"不安全连接"拦截
        chrome_options.add_argument("--unsafely-treat-insecure-origin-as-secure=http://10.10.9.9,http://123.123.123.123")
        
        # 设置窗口大小,防止 headless 模式下元素重叠或不显示
        chrome_options.add_argument("--window-size=1920,1080")

        try:
            print("正在启动 Chrome...")
            self.driver = webdriver.Chrome(options=chrome_options)
        except Exception as e:
            logging.error(f"启动 Chrome 失败: {e}")
            print("提示:请确保网络正常或驱动已正确下载。")
            exit(1)

    # 登录校园网
    def login_campus_network(self):
        driver = self.driver
        max_attempts = 3
        attempts = 0

        while attempts < max_attempts:
            try:
                print(f"正在访问登录页面... 第 {attempts + 1} 次尝试")
                driver.get('http://10.10.9.9/')
                time.sleep(3) # 等待页面跳转

                # 检查是否已经登录 (根据 HTML, 可能没有 toLogOut,这里可以根据标题判断)
                if "成功" in driver.title or "已经登录" in driver.page_source:
                    print("检测到已经登录成功。")
                    return

                # 登录流程
                try:
                    # 使用 ActionChains 防止普通交互失败
                    actions = ActionChains(driver)

                    print("正在输入用户名...")
                    # 尝试处理用户名提示框遮挡问题
                    try:
                        username_tip = driver.find_element(By.ID, 'username_tip')
                        if username_tip.is_displayed():
                            print("检测到用户名提示遮罩,正在点击...")
                            # 尝试点击遮罩
                            try:
                                username_tip.click()
                            except:
                                actions.click(username_tip).perform()
                            time.sleep(0.5)
                    except:
                        pass

                    username_input = WebDriverWait(driver, 10).until(
                        EC.element_to_be_clickable((By.ID, 'username'))
                    )
                    username_input.clear()
                    # 回退到普通输入方式,防止 ActionChains 在某些情况下失效
                    try:
                         username_input.click()
                         username_input.send_keys('23721830')
                    except:
                         print("普通输入失败,尝试 ActionChains...")
                         actions.click(username_input).send_keys('xxxxxxx').perform()
                    
                    time.sleep(1) # 增加短暂等待

                    print("正在输入密码...")
                    try:
                        pwd_tip = driver.find_element(By.ID, 'pwd_tip')
                        if pwd_tip.is_displayed():
                            print("检测到密码提示遮罩,正在点击...")
                            actions.click(pwd_tip).perform()
                            time.sleep(0.5)
                    except Exception as e:
                        print(f"尝试点击提示遮罩时忽略错误: {e}")

                    password_input = WebDriverWait(driver, 10).until(
                        EC.element_to_be_clickable((By.ID, 'pwd'))
                    )
                    password_input.clear()
                    actions.click(password_input).send_keys('xxxxxxxx').perform()

                    print("正在点击登录按钮...")
                    # 直接点击 a 标签
                    login_button = WebDriverWait(driver, 10).until(
                        EC.element_to_be_clickable((By.ID, 'loginLink'))
                    )
                    # login_button.click()
                    actions.click(login_button).perform()

                    # 等待登录结果
                    time.sleep(5)
                    if self.check_network_connection():
                        print("校园网登录成功!")
                        return
                    else:
                        print("登录后网络仍未通,可能账户密码错误或欠费。")
                        driver.save_screenshot('error_result.png')
                
                except Exception as e:
                    print(f"操作页面元素时出错: {e}")
                    traceback.print_exc()
                    driver.save_screenshot(f'error_step_{attempts}.png')
                    attempts += 1

            except Exception as e:
                print(f"页面加载出错: {e}")
                attempts += 1
            
            time.sleep(2)

        print("达到最大尝试次数,登录失败。")

    # 检查网络是否可以 ping 通百度
    def check_network_connection(self):
        try:
            # Windows 下 ping 参数是 -n
            result = subprocess.run(['ping', '-n', '1', 'www.baidu.com'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            return result.returncode == 0
        except Exception as e:
            print(f"检查网络连接时出错: {e}")
            return False

    # 检查网络连接状态
    def check_and_login(self):
        if self.check_network_connection():
            print("网络连接正常,无需登录。")
        else:
            print("网络无法连接,尝试登录校园网...")
            self.login_campus_network()

# 创建 CampusNetworkLogin 实例并调用 check_and_login 函数
campus_network = CampusNetworkLogin()
campus_network.check_and_login()
相关推荐
weisian1511 小时前
进阶篇-4-数学篇-3--深度解析AI中的向量概念:从生活到代码,一文吃透核心逻辑
人工智能·python·生活·向量
写代码的【黑咖啡】1 小时前
Python中的Msgpack:高效二进制序列化库
开发语言·python
MistaCloud1 小时前
Pytorch进阶训练技巧(二)之梯度层面的优化策略
人工智能·pytorch·python·深度学习
AIFQuant1 小时前
2026 全球股市实时行情数据 API 对比指南
python·websocket·金融·数据分析·restful
爱吃肉的鹏1 小时前
使用Flask在本地调用树莓派摄像头
人工智能·后端·python·flask·树莓派
2501_944526422 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 主题切换实现
android·开发语言·javascript·python·flutter·游戏·django
深蓝电商API2 小时前
Selenium处理iframe嵌套页面实战
爬虫·python·selenium
一晌小贪欢2 小时前
Python 健壮性进阶:精通 TCP/IP 网络编程与 requirements.txt 的最佳实践
开发语言·网络·python·网络协议·tcp/ip·python基础·python小白
weixin_395448912 小时前
mult_yolov5_post_copy.c_cursor
linux·人工智能·python