上海应用大学网课自动化学习脚本(基于Python selenium) —— 技术笔记

在闲暇线上学习中,网课平台通常要求手动点击播放、逐节观看视频,效率较低,对于工作人士时间较紧。本文介绍一个基于 Python + Selenium 的自动化脚本,能够模拟用户操作,实现课程自动播放与章节跳转,仅作技术交流使用,目前所实现功能仅为单节课程的刷课,更换课程刷课需要修改Entercourse函数内的Xpath。

  1. 浏览器配置与页面访问

脚本使用 Edge 浏览器(Chromium 内核)作为自动化载体,启动浏览器后自动访问学习网站首页。在页面加载完成后,脚本会等待一定时间,确保页面元素渲染完成,为后续操作做好准备。

  1. 密码登录跳转

平台默认可能使用扫码登录,脚本会自动切换到密码登录模式。通过等待并自动点击相应选项,脚本能够顺利进入用户名和密码输入界面,从而为自动登录做准备。

  1. 自动登录

脚本会自动输入用户的账号和密码,点击登录按钮完成登录操作。验证码仍需手动拖动验证(手动验证需要10s内完成,否则会登陆失败)。登录成功后,脚本会等待页面跳转完成,确保后续操作能够顺利进行。如果登录失败,脚本会捕获异常并提示用户。

  1. 查看全部课程与进入课程

登录后,脚本会点击“查看全部”按钮进入课程列表页面。用户可以进入指定课程,也可以通过翻页功能访问后续课程列表,从而实现全量课程的浏览和播放。

  1. 视频播放与时间管理

进入课程播放页面后,脚本会自动点击播放按钮开始视频。通过解析页面显示的当前观看时长和视频总时长,脚本能够实时计算播放进度。总时间会被转换为秒数,以便进行逻辑判断,确保视频播放达到应观看时长。

  1. 自动章节切换

当检测到视频播放完成后,脚本会自动点击“下一章节”按钮进入下一节课程,并继续播放。即便在某些情况下未能获取时间信息或按钮不可点击,脚本也会尝试刷新页面并重新播放,保证播放流程不中断。

  1. 自动播放循环

脚本核心逻辑是循环监测视频播放进度。如果当前章节未播放完成,脚本会持续等待并定期检查。播放完成后自动跳转到下一章节,直至所有课程播放完毕,实现全程自动化。

  1. 元素安全操作与异常处理

为了提高稳定性,脚本封装了安全的元素点击和定位函数,并捕获页面刷新或元素失效可能导致的异常。这些机制确保在不同浏览器状态下,脚本都能够顺利执行。

  1. 执行流程

整个脚本按照明确流程执行:先切换到密码登录,再自动登录、查看全部课程、进入课程播放页面,然后开始自动播放视频并循环切换章节。该流程保证了从登录到课程完成的全程自动化。

总结

通过这个脚本,实现了网课自动播放、章节自动切换、播放进度监测等功能,提供了完整的学习自动化流程。该项目仅用于技术交流与 Python 自动化练习,实际使用时仍需遵守学校和平台的相关规定。

代码如下:

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
import time
from selenium.common.exceptions import StaleElementReferenceException

#***********************************开发版:上海应用大学网课自动刷视频***********************************

# 配置 Edge 浏览器
edge_options = webdriver.EdgeOptions()
edge_options.use_chromium = True
driver = webdriver.Edge(options=edge_options)

# 访问学习网站
driver.get("https://www.learnin.com.cn/#/login")
time.sleep(6)  # 等待页面加载

# **跳转密码登录**
def jumpPasswd():
    try:
        wait = WebDriverWait(driver, 10)
        password_tab = wait.until(EC.element_to_be_clickable(
            (By.XPATH, '//*[@id="app"]/div/div/div/div[1]/div[2]/div/div[1]/div[1]/div/label[2]')))
        password_tab.click()
        print("✅ 密码登录跳转成功")
    except Exception as e:
        print("❌ 密码登录跳转失败:", e)

# **自动登录******需要手动进行拖动验证码验证*************
def login():
    try:
        username_input = 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 = 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 = 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)
        print("✅ 登录成功")
    except Exception as e:
        print(f"❌ 登录失败: {e}")

# **查看全部**
def Viewall():
    try:
        wait = WebDriverWait(driver, 10)
        learn_button = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="studentHomeStep4"]/div/div[1]/div/a')))
        learn_button.click()
        time.sleep(2)
        print("✅ 进入查看全部成功")
    except Exception as e:
        print("❌ 进入查看全部失败:", e)

# **进入课程**
def Entercourse():
    try:
        wait = WebDriverWait(driver, 10)
        learn_button = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/div[2]/div[2]/a')))
        learn_button.click()
        time.sleep(2)
        print("✅ 进入课程成功")
    except Exception as e:
        print("❌ 进入课程失败:", e)

# **翻页2**
def Clickpage2():
    try:
        # driver.switch_to.window(driver.window_handles[-1])  # 打开新窗口需要切换到新窗口
        wait = WebDriverWait(driver, 10)
        learn_button_1 = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div[2]/div[1]/div[2]/div[2]/div/ul/li[2]')))
        learn_button_1.click()
        time.sleep(5)
        print("✅ 进入翻页第2页成功")
    except Exception as e:
        print("❌ 进入翻页第2页失败:", e)

# **点击播放视频**
def ClicklearnVideo():
    try:
        driver.switch_to.window(driver.window_handles[-1])  # 切换到新窗口
        wait = WebDriverWait(driver, 10)
        play_button = wait.until(EC.element_to_be_clickable((By.XPATH,
                                                             '//*[@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')))
        play_button.click()
        print("🎬 视频开始播放")
        time.sleep(2)
    except Exception as e:
        print("❌ 播放视频失败:", e)

# **将时间字符串转换为秒数**
def time_to_seconds(time_str):
    try:
        h, m, s = map(int, time_str.split(":"))
        return h * 3600 + m * 60 + s
    except:
        return 0  # 如果解析失败,返回 0 秒

# **点击下一章节**
def click_next_chapter(wait):
    try:
        # 重新定位元素
        next_button = wait.until(EC.element_to_be_clickable(
            (By.XPATH, '//*[@id="app"]/div/div[1]/div[1]/div[3]/div[3]/button')))
        next_button.click()
        print("➡️ 跳转到下一章节")
        time.sleep(5)  # 等待新视频加载
        ClicklearnVideo()  # 播放新视频
    except Exception as e:
        print("❌ 无法点击“下一章节”:", e)

# **自动播放视频**
def auto_play_videos():
    while True:
        try:
            while True:
                wait = WebDriverWait(driver, 10)
                time.sleep(10)
                # 获取观看时长和当前已观看时长

                try:
                    Btime_elements = wait.until(EC.presence_of_all_elements_located(
                        (By.XPATH,
                         '//*[@id="app"]/div/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/div/div/div[3]/div[2]/span[2]')))
                    # print(f"当前时间{Btime_elements}")
                    # **如果找不到观看时间,直接跳转下一章节**
                    if not Btime_elements:
                        print("⚠️ 未检测到观看时间,跳转到下一章节")
                        click_next_chapter(wait)
                        continue

                    Etime_elements = wait.until(EC.presence_of_all_elements_located(
                        (By.XPATH,
                         '//*[@id="app"]/div/div[1]/div[2]/div[1]/div/div[2]/div/div[2]/div/div/div[3]/div[2]/span[3]')))

                except Exception as e:
                    # 如果获取时间失败,直接跳到下一章节
                    print("⚠️ 未检测到已观看时间,跳转到下一章节")
                    click_next_chapter(wait)
                    continue

                # 获取文本内容
                Btime_str = Btime_elements[0].text.strip()
                Etime_str = Etime_elements[0].text.strip()
                # print(f"当前时间{Btime_str}总时间{Etime_str}")
                # **转换时间**
                Btime_seconds = time_to_seconds(Btime_str) / 0.7
                Etime_seconds = time_to_seconds(Etime_str)

                print(f"🎞 观看时长应达到: {Btime_seconds}秒")
                print(f"🎞 当前已观看: {Etime_seconds}秒")

                # **播放完成,点击下一章节**
                if Etime_seconds >= Btime_seconds:
                    print(f"观看时长{Etime_seconds}大于总时长{Btime_seconds}✅ 视频播放完成,准备跳转下一章")
                    click_next_chapter(wait)
                else:
                    print("▶️ 正在播放中")
                    time.sleep(5)  # 每 5 秒检查一次播放进度

        except Exception as e:
            print("❌ 发生错误:", e)
            driver.refresh()   #发生错误刷新页面
            time.sleep(5)   #等待加载
            ClicklearnVideo()    #重新播放视频

# 定位元素前先刷新它
def find_element(driver, locator):
    return WebDriverWait(driver, 10).until(EC.presence_of_element_located(locator))

# **点击元素的安全函数**
def safe_click(xpath):
    try:
        element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, xpath)))
        element.click()
    except StaleElementReferenceException:
        # 重新查找并点击
        element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, xpath)))
        element.click()

# **执行任务**
jumpPasswd()
login()
Viewall()
# Clickpage2()
Entercourse()
ClicklearnVideo()
auto_play_videos()
posted @ 2025-09-23 14:25  小神龙_007  阅读(104)  评论(0)    收藏  举报