自动登录上海大学校园

项目地址: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()
相关推荐
炸炸鱼.18 小时前
Python 操作 MySQL 数据库
android·数据库·python·adb
_深海凉_19 小时前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦19 小时前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu20 小时前
Python 语法之数据结构详细解析
python
AI问答工程师20 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan52021 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕21 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙21 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
小贾要学习21 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
格鸰爱童话1 天前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习