当前位置: 首页 > news >正文

上海应用大学网课自动化学习脚本(基于Python selenium)代码重构为GUI界面 —— 技术笔记

在之前原有功能的基础上,新增了基于 PyQt5 的图形化用户界面(GUI),提升了操作体验和可视化程度,主要功能包括:

1. 日志显示区

界面上方新增一个 日志窗口(QTextEdit)。

程序运行过程中产生的所有提示、执行进度、错误信息都会实时输出到日志区。

日志会自动滚动到最新位置,方便用户查看。

2. 控制区(三个主要组件)

输入框(QLineEdit)

用于输入或修改 Entercourse 的 XPath。

这个 XPath 是进入具体课程的关键定位符,用户可根据需要手动修改。

“开始自动执行”按钮(QPushButton)

点击后会自动启动 Edge 浏览器并打开指定学习网站。

程序自动完成以下步骤:

切换到密码登录页面

自动输入账号密码并登录

点击“查看全部”进入课程列表

使用输入框中的 XPath 定位并进入指定课程

开始播放课程视频,并进入自动刷课逻辑

“关闭浏览器”按钮(QPushButton)

点击后会停止自动执行线程,并关闭当前 Edge 浏览器。

保证不会因为强制关闭而导致残留的后台浏览器进程。

3. 备注说明区

在控制区按钮下方新增了一行 说明性文本(QLabel):

“备注: Entercourse XPath 为应刷课程的 XPath”

主要是帮助用户理解输入框的用途,避免误操作。

重构后代码如下:

import sys
import time
import threading
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QTextEdit, QLineEdit, QLabel
from PyQt5.QtCore import pyqtSignal, QObject
from selenium import webdriver
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.common.exceptions import StaleElementReferenceException#***********************************GUI开发版:上海应用大学网课自动刷视频***********************************# ---------------- 日志信号 ----------------
class Logger(QObject):log_signal = pyqtSignal(str)def __init__(self):super().__init__()def log(self, msg):self.log_signal.emit(msg)# ---------------- Selenium 自动执行线程 ----------------
class AutoPlayThread(threading.Thread):def __init__(self, driver, entercourse_xpath, logger):super().__init__()self.driver = driverself.entercourse_xpath = entercourse_xpathself.running = Trueself.logger = loggerdef log(self, msg):self.logger.log(msg)# 安全点击def safe_click(self, xpath):for _ in range(3):if not self.running:return Falsetry:element = WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, xpath)))element.click()return Trueexcept StaleElementReferenceException:time.sleep(1)return False# 安全获取文本def safe_get_text(self, xpath):for _ in range(3):if not self.running:return ""try:element = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath)))return element.text.strip()except StaleElementReferenceException:time.sleep(1)return ""def time_to_seconds(self, time_str):try:h, m, s = map(int, time_str.split(":"))return h*3600 + m*60 + sexcept:return 0# ---------------- 自动化功能 ----------------def jumpPasswd(self):if self.safe_click('//*[@id="app"]/div/div/div/div[1]/div[2]/div/div[1]/div[1]/div/label[2]'):self.log("✅ 密码登录跳转成功")else:self.log("❌ 密码登录跳转失败")def login(self):try:username_input = self.driver.find_element(By.XPATH,'//*[@id="app"]/div/div/div/div[1]/div[2]/div/div[1]/div[2]/div/form/div[1]/div/div/input')password_input = self.driver.find_element(By.XPATH,'//*[@id="app"]/div/div/div/div[1]/div[2]/div/div[1]/div[2]/div/form/div[2]/div/div[1]/input')login_button = self.driver.find_element(By.XPATH,'//*[@id="app"]/div/div/div/div[1]/div[2]/div/div[1]/div[2]/div/div/div/button')time.sleep(1)username_input.send_keys("15346111559")password_input.send_keys("Xzl19980216")login_button.click()time.sleep(3)self.log("✅ 登录成功")except Exception as e:self.log(f"❌ 登录失败: {e}")def Viewall(self):if self.safe_click('//*[@id="studentHomeStep4"]/div/div[1]/div/a'):self.log("✅ 进入查看全部成功")time.sleep(2)else:self.log("❌ 进入查看全部失败")def Entercourse(self):if self.safe_click(self.entercourse_xpath):self.log("✅ 进入课程成功")time.sleep(2)else:self.log("❌ 进入课程失败")def ClicklearnVideo(self):try:self.driver.switch_to.window(self.driver.window_handles[-1])if self.safe_click('//*[@id="app"]/div/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/div/div/div[2]/div/div/div[2]/div/div[1]/div[2]/div[2]/div[1]/button'):self.log("🎬 视频开始播放")time.sleep(2)else:self.log("❌ 播放视频失败")except Exception as e:self.log(f"❌ 播放视频失败: {e}")def click_next_chapter(self):if self.safe_click('//*[@id="app"]/div/div[1]/div[1]/div[3]/div[3]/button'):self.log("➡️ 跳转到下一章节")time.sleep(5)self.ClicklearnVideo()else:self.log("❌ 无法点击“下一章节”")def auto_play_videos(self):while self.running:try:time.sleep(5)Btime_str = self.safe_get_text('//*[@id="app"]/div/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/div/div/div[3]/div[2]/span[2]')Etime_str = self.safe_get_text('//*[@id="app"]/div/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/div/div/div[3]/div[2]/span[3]')if not Btime_str or not Etime_str:self.log("⚠️ 未检测到时间,跳转下一章节")self.click_next_chapter()continueBtime_seconds = self.time_to_seconds(Btime_str) / 0.7Etime_seconds = self.time_to_seconds(Etime_str)self.log(f"🎞 观看时长应达到: {Btime_seconds}秒")self.log(f"🎞 当前已观看: {Etime_seconds}秒")if Etime_seconds >= Btime_seconds:self.log("✅ 视频播放完成,准备跳转下一章")self.click_next_chapter()except Exception as e:self.log(f"❌ 播放出错: {e}")self.driver.refresh()time.sleep(3)self.ClicklearnVideo()def stop(self):self.running = Falsetry:self.driver.quit()self.log("🛑 浏览器已关闭")except:pass# ---------------- GUI 界面 ----------------
class LearnInGUI(QWidget):def __init__(self):super().__init__()self.setWindowTitle("上海应用大学网课自动刷视频")self.setGeometry(100, 100, 800, 600)self.thread = Noneself.driver = Noneself.logger = Logger()self.logger.log_signal.connect(self.log)layout = QVBoxLayout()self.setLayout(layout)# 日志显示self.log_text = QTextEdit()self.log_text.setReadOnly(True)layout.addWidget(self.log_text)# 控制区域control_layout = QHBoxLayout()control_layout.addWidget(QLabel("Entercourse XPath:"))self.entercourse_input = QLineEdit('//*[@id="app"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/div[2]/div[2]/a')control_layout.addWidget(self.entercourse_input)self.start_btn = QPushButton("开始自动执行")self.start_btn.clicked.connect(self.start_auto)control_layout.addWidget(self.start_btn)self.stop_btn = QPushButton("关闭浏览器")self.stop_btn.clicked.connect(self.stop_browser)control_layout.addWidget(self.stop_btn)layout.addLayout(control_layout)# **新增一行文本备注**self.xpath_note = QLabel("备注: Entercourse XPath为应刷课程的 XPath")layout.addWidget(self.xpath_note)def log(self, msg):self.log_text.append(msg)self.log_text.verticalScrollBar().setValue(self.log_text.verticalScrollBar().maximum())def start_auto(self):if self.thread is None:edge_options = webdriver.EdgeOptions()edge_options.use_chromium = Trueself.driver = webdriver.Edge(options=edge_options)self.driver.get("https://www.learnin.com.cn/#/login")time.sleep(5)entercourse_xpath = self.entercourse_input.text().strip()self.thread = AutoPlayThread(self.driver, entercourse_xpath, self.logger)# 按顺序执行初始化任务self.thread.jumpPasswd()self.thread.login()self.thread.Viewall()self.thread.Entercourse()self.thread.ClicklearnVideo()# 启动自动播放线程threading.Thread(target=self.thread.auto_play_videos, daemon=True).start()self.log("🚀 自动执行开始")def stop_browser(self):if self.thread:self.thread.stop()self.thread = Noneself.log("🛑 自动执行已停止")# ---------------- 主程序 ----------------
if __name__ == "__main__":app = QApplication(sys.argv)gui = LearnInGUI()gui.show()sys.exit(app.exec_())
http://www.sczhlp.com/news/131315/

相关文章:

  • 网站配置优化做食品网站有哪些内容
  • 用.net core 做网站国外黑色背景网站
  • 四川seo整站优化费用接私活做网站要不要签合同
  • 哈尔滨开网站天津科技网站
  • dw做的网站与浏览器不匹配wordpress怎么修改导航栏
  • 上海微信网站公司哪家好安阳市商祺网络有限责任公司
  • 网站怎么防k上海集团网站建设咨询
  • 做冷饮的网站wordpress 臃肿
  • 北京网站软件制作班级同学录网站建设
  • 做得不好的知名企业网站永久免费建站网站
  • 搞笑网站模板开发者模式在哪里打开
  • 百度提问google关键词优化排名
  • 三台网站建设哪家专业夺宝网站怎样做优化
  • 做测算的网站wordpress4 sqlite
  • 企业网站seo推广重庆的企业的网站建设
  • php网站开发实战开发龙之向导外贸网址
  • 建网站需多少钱长春南关网站建设
  • 建设银行网络连接异常网站服务器失去响应网站栏目建设
  • 网站没备案能百度推广吗游戏开发需要的软件
  • 企业网站网页施工企业质量管理体系应按照我国
  • AT_abc201_f [ABC201F] Insertion Sort 题解
  • 餐饮网站建设有什么好处网页模板图片
  • 中国正能量不良网站直接进入wordpress iframe
  • 兰州做网站客户研究院网站建设
  • 贸易网站设计互联网销售可以卖什么产品
  • 中小型企业网站优化企业融资只有两种方法
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • c语言动态内存分配
  • 2025.9.24——1橙
  • 乐清柳市网站建设公司2021年uc秒懂网址