自动刷课
项目场景:刷课赚取积分
需求背景:每天刷课时操作都一样,打开浏览器,选择未选课程,开始看课,评估课程,课后评测...
项目内容:思考是否可以使用自动化脚本实现自动刷课
实现方式
查询实现方式
deepseek 询问 浏览器页面上自动点击按钮,可以用什么语言实现
选择实现方式
首先排除 JavaScript/Node.js 考虑提示是“专为 Chrome/Chromium 设计”,故排除。
在 Java + Selenium WebDriver 和 Python + Selenium 中考虑
deepseek 询问 Python 的Selenium 和Java 的Selenium WebDriver 是一致的吗?
最终考虑自己只是想快速实现 个人刷课场景,选择Python + Selenium 方案。
环境安装
python
# 使用 homebrew 安装 python
brew install python
python --version
#output Python 3.9.6
which python
#output python: aliased to python3
which python3
#output python3: aliased to /usr/bin/python3
python3 -m sysconfig | grep 'PREFIX'
#output PYTHONFRAMEWORKPREFIX = "/Applications/Xcode.app/Contents/Developer/Library/Frameworks"
通过 output 知shell中使用的还是mac自带的python,而不是homebrew安装的。
如果是homebrew安装的python应该输出路径是 /opt/homebrew/bin/python3
疑问: 为什么我使用了 homebrew 安装了 python,shell 中还是自带的python呢?
查看 ~/.zshrc 或 ~/.bash_profile 中发现有
python3: aliased to /usr/bin/python3
。查看
echo $PATH
中发现/opt/homebrew/bin
在/usr/bin
前。结论:别名的优先级高于 $PATH,在 $PATH 中的优先级按照先后顺序,所以python3指向系统自带python。
pip
pip --version
#output zsh: command not found: pip
pip3 --version
#output pip 25.0 from /opt/homebrew/lib/python3.13/site-packages/pip (python 3.13)
which pip3
#output /opt/homebrew/bin/pip3
pip3 show pip
# Name: pip
# Version: 25.0
# Summary: The PyPA recommended tool for installing Python packages.
# Home-page: https://pip.pypa.io/
# Author:
# Author-email: The pip developers <distutils-sig@python.org>
# License: MIT
# Location: /opt/homebrew/lib/python3.13/site-packages
# Requires:
# Required-by:
通过执行pip命令得知系统里已经有pip3,再查询路径得知是homebrew安装的,确定未主动安装过pip3,查阅资料知是brew安装python的时候安装了pip。
selenium
pip install selenium
项目启动
浏览器驱动
下载的驱动必须和本地浏览器保证一致,一开始使用的是chrome驱动。
chromeDriver 下载地址:需要🪜。
# 查看本地chrome版本
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
#output Google Chrome 133.0.6943.127
但是通过下载地址中未发现一致版本。
改为使用 webdriver_manager
自动下载浏览器驱动。
pip install webdriver_manager
webdriver-manager的主要作用
在使用 Selenium 进行自动化测试或网页抓取时,通常需要一个浏览器驱动程序(例如 Chrome 浏览器需要 ChromeDriver)。这些驱动程序必须与浏览器版本兼容。
尝试点击按钮
使用命令启动chrome
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
启动后打开到对应网址,通过F12后得知 关闭 按钮的 id 是goBack
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
# 使用 webdriver_manager 自动管理 ChromeDriver 并自动选择合适版本
service = Service(ChromeDriverManager().install())
# 设置 ChromeOptions 以附加到已有的 Chrome 浏览器会话
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
# 初始化 WebDriver 使用 service 和 options 参数
driver = webdriver.Chrome(service=service, options=chrome_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
print(f"当前窗口句柄: {window_handles}")
# 切换到第一个窗口句柄(假设这是你已经打开的窗口)
if window_handles:
driver.switch_to.window(window_handles[0])
print(f"切换到窗口句柄: {window_handles[0]}")
# 使用显式等待确保元素加载完成
try:
print("等待按钮元素加载完成...")
button = WebDriverWait(driver, 2).until(
EC.element_to_be_clickable((By.ID, "goBack"))
)
print("按钮元素已加载,准备点击...")
# 使用 JavaScript 点击按钮
driver.execute_script("arguments[0].click();", button)
print("按钮已成功点击!")
except Exception as e:
print(f"点击按钮时出错:{e}")
# 不关闭浏览器,以便观察效果
# driver.quit()
执行报错:
/Users/tianci/PycharmProjects/autoRushCourse/.venv/lib/python3.9/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
通过报错提示信息去 https://github.com/urllib3/urllib3/issues/3020
查看解决办法。
# 卸载urllib3
pip uninstall urllib3
# 指定版本重新安装
pip install urllib3==1.26.15
再次执行,等待一会儿后(应该是在下载 chrome 驱动)发现已经自动点击成功了!!
查看驱动安装目录,已经下载好了对应版本。
chrome换edge
而当我每次电脑更换wifi或者重启之后,再使用chrome会报错
报错:
selenium.common.exceptions.WebDriverException: Message: Service /Users/tianci/.wdm/drivers/chromedriver/mac64/133.0.6943.126/chromedriver-mac-arm64/chromedriver unexpectedly exited. Status code was: -9
当我挂上🪜后就没问题了...
而当我打开启动日志,发现chrome版本是 133.0.6943.127
,而使用的驱动使用的确实 133.0.6943.126
...
考虑chrome版本错乱以及第一次启用必须挂上🪜,决定改为edge驱动。
# 尝试解决问题命令
# 更新 webdriver_manager 和selenium
pip install --upgrade webdriver_manager selenium
# 查看 webdriver_manager
pip show webdriver_manager
#output
# Name: webdriver-manager
# Version: 4.0.2
# Summary: Library provides the way to automatically manage drivers for different browsers
# Home-page: https://github.com/SergeyPirogov/webdriver_manager
# Author: Sergey Pirogov
# Author-email: automationremarks@gmail.com
# License:
# Location: /Users/tianci/PycharmProjects/autoRushCourse/.venv/lib/python3.9/site-packages
# Requires: packaging, python-dotenv, requests
# Required-by:
当驱动从 chrome 换成 edge时,启动没有问题。
使用命令启动edge
/Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge --remote-debugging-port=9222
完整路径如下图
编写程序
介绍整个流程
整个流程分为3个大部分。
- 观看视频:1倍速改10倍速播放,每个视频看完能自动点击下一节,最后点击下一步到课程评估。
- 评估答题:看完视频后能自动评估课程,完成答题。
- 从打开网址到登录一直到观看视频实现自动化,接上第一部分。
第一部分
涉及操作:
- 点击页面上id是app的元素(随便选的元素,使用
ActionChains
模拟用户点击操作。程序点击暂停/播放按钮失败,因为页面做了限制,用户必须先点击页面任意一处或滑动/操作页面后,自动点击才能生效。) - 将1.0x改为10.0x,点击2.0x(点击 2 倍速是因为当自动打开播放页面,选择 10 倍速后,会卡在前2秒循环播放,我的解决办法是先用 2 倍速过渡一下。)
- 点击改后的 10 倍速。
- while 循环每5秒判断「下一节」「下一步」按钮是否出现,出现则点击。
改倍速 OneAutoChangeTen.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.common.action_chains import ActionChains
import time
def OneAutoChangeTen():
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Edge(service=service, options=edge_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[0])
try:
# 等待页面完全加载
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
print("页面完全加载")
# 检查是否在 iframe 中
iframes = driver.find_elements(By.TAG_NAME, "iframe")
if iframes:
# print(f"找到 {len(iframes)} 个 iframe,尝试切换到每个 iframe 查找元素...")
for iframe in iframes:
driver.switch_to.frame(iframe)
try:
# 模拟用户点击操作
app_btn = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.ID, "app"))
)
actions = ActionChains(driver)
actions.move_to_element(app_btn).click().perform()
print("模拟用户点击操作")
# doubleSpeedOperate_list(倍速父标签)
double_speed_operate_list = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.ID, "doubleSpeedOperate_list"))
)
time.sleep(5)
dso_items = double_speed_operate_list.find_elements(By.CLASS_NAME, "dso-item")
# 查找包含 1.0x 的元素并修改成 10.0x,并点击
target_item = None
for item in dso_items:
text_content = driver.execute_script("return arguments[0].textContent;", item)
if text_content.strip() == '1.0x':
time.sleep(2)
driver.execute_script("arguments[0].textContent = '10.0x';", item)
print("1.0x 修改为 10.0x")
target_item = item
elif text_content.strip() == '2.0x':
time.sleep(2)
driver.execute_script("arguments[0].click();", item)
print("点击了 2.0x 元素")
if target_item:
time.sleep(5)
driver.execute_script("arguments[0].click();", target_item)
print("点击了 10.0x 元素")
# 切换回默认内容,避免后续查找操作导致错误
driver.switch_to.default_content()
break
else:
print("未找到包含 10.0x 的元素")
except Exception as e:
print(f"在当前 iframe 中未找到元素: {e}")
driver.switch_to.default_content()
else:
print("没有找到 iframe,直接查找元素...")
except Exception as e:
print(f"操作时出错:{e}")
判断下一节 ClickNextChapter.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.microsoft import EdgeChromiumDriverManager
def ClickNextChapter():
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Edge(service=service, options=edge_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[0])
try:
# 等待页面完全加载
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
iframes = driver.find_elements(By.TAG_NAME, "iframe")
if iframes:
for iframe in iframes:
driver.switch_to.frame(iframe)
try:
next_button = driver.find_element(By.CLASS_NAME, "next-button")
driver.execute_script("arguments[0].click();", next_button)
print("「下一节」按钮已出现,点击!")
return 1
except:
print("「下一节」按钮未出现")
return 0
else:
print("没有找到 iframe,直接查找元素...")
except Exception as e:
print(f"操作时出错:{e}")
判断下一步 ClickNextPage.py
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.microsoft import EdgeChromiumDriverManager
def ClickNextPage():
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Edge(service=service, options=edge_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[0])
# print(f"切换到窗口句柄: {driver.title}")
# print(f"当前窗口句柄: {window_handles}")
# # 打印所有窗口标题
# for handle in window_handles:
# driver.switch_to.window(handle)
# print(f"窗口标题: {driver.title}")
#
# # 切换到第二个窗口句柄(假设这是你已经打开的窗口)
# if len(window_handles) >= 2:
# driver.switch_to.window(window_handles[1])
# print(f"切换到窗口句柄: {driver.title}")
try:
next_step = driver.find_element(By.ID, "goNextStep")
if "hide" in next_step.get_attribute("class"):
raise Exception("Element has 'hide' class")
driver.execute_script("arguments[0].click();", next_step)
print("「下一步」按钮已出现,点击!")
return 1
except:
print("「下一步」按钮未出现")
return 0
循环判断 StartClass.py
from ClickNextChapter import ClickNextChapter
from OneAutoChangeTen import OneAutoChangeTen
from ClickNextPage import ClickNextPage
from CurriculumEvaluation import CurriculumEvaluation
from AfterClassInspection import AfterClassInspection
import time
def StartClass():
try:
print("开始观看课程···")
# 进入课程先改成 10 倍速
OneAutoChangeTen()
time.sleep(2)
while True:
print("查看「下一节」按钮是否出现?")
result = ClickNextChapter()
if result == 1:
print("等待5秒后自动改倍速···")
time.sleep(5)
OneAutoChangeTen()
elif result == 0:
print("查看「下一步」按钮是否出现?")
page = ClickNextPage()
if page == 1:
break
# 等待 5 秒后再次检查
time.sleep(5)
print("等待3秒后开始课程评估···")
time.sleep(3)
CurriculumEvaluation()
print("等待3秒后开始课后测试···")
time.sleep(3)
inspection = AfterClassInspection()
if inspection == 1:
print("结束课后测试")
else:
print("补考开始")
AfterClassInspection()
print("补考结束")
print("结束课后测试")
finally:
print("程序结束")
第二部分
评估课程涉及操作:
- 评星级
- 评分
- 点击 下一步
- 点击 确定
- 点击 进入下一步
课程评估 CurriculumEvaluation.py
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.microsoft import EdgeChromiumDriverManager
import time
def CurriculumEvaluation():
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Edge(service=service, options=edge_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[0])
# print(f"切换到窗口句柄: {driver.title}")
try:
radio_button = driver.find_element(By.XPATH, '//input[@type="radio" and @name="score" and @value="5"]')
driver.execute_script("arguments[0].click();", radio_button)
print("评星级成功")
time.sleep(1)
elements = driver.find_elements(By.XPATH, '//p[@class="cs-option-row" and text()="5分"]')
# 挨个点击这些元素
for element in elements:
driver.execute_script("arguments[0].click();", element)
print("评分 5 分成功")
time.sleep(1)
# 找到并点击下一步按钮
submit_button = driver.find_element(By.XPATH, '//button[@type="submit" and contains(@class, "goNextStep")]')
driver.execute_script("arguments[0].click();", submit_button)
print("点击下一步成功")
time.sleep(1)
# 找到并点击确定按钮
confirm_button = driver.find_element(By.XPATH, '//a[@class="layui-layer-btn1" and text()="确定"]')
driver.execute_script("arguments[0].click();", confirm_button)
print("点击确定成功")
time.sleep(1)
# 找到并点击进入下一步按钮
next_step_button = driver.find_element(By.XPATH, '//a[@class="layui-layer-btn1" and text()="进入下一步"]')
driver.execute_script("arguments[0].click();", next_step_button)
print("点击进入下一步成功")
time.sleep(1)
except:
print("评分失败")
课后测试涉及操作:
- 单选题全选最后一个(D选项)
- 多选题全选
- 判断题选择正确(经测试,自动选择的话,这样能过 60 分的可能性比较大)
- 点击 提交
- 点击 确定
- 判断点击确定后是否出现 查看详情(出现=满60分,可结束;未出现=未及格,需要补考)
课后测试 AfterClassInspection.py
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.microsoft import EdgeChromiumDriverManager
import time
def AfterClassInspection():
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Edge(service=service, options=edge_options)
# 获取所有窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[0])
# print(f"切换到窗口句柄: {driver.title}")
try:
# 单选选 D,多选全选
acceptance_elements = driver.find_elements(By.XPATH,'//p[@class="cs-option-row"]')
for element in acceptance_elements:
driver.execute_script("arguments[0].click();", element)
print("填单选+多选题成功")
time.sleep(1)
# 判断题选正确
right_elements = driver.find_elements(By.XPATH, '//p[@class="cs-option-row" and text()="正确"]')
for element in right_elements:
driver.execute_script("arguments[0].click();", element)
print("填判断题成功")
time.sleep(1)
# 点击提交
next_step = driver.find_element(By.ID, "goNext")
driver.execute_script("arguments[0].click();", next_step)
print("点击提交成功")
time.sleep(1)
# 点击确定
confirm_button = driver.find_element(By.XPATH, '//a[@class="layui-layer-btn1" and text()="确定"]')
driver.execute_script("arguments[0].click();", confirm_button)
print("点击确定成功")
time.sleep(1)
# 点击查看详情(补考)
detail_button = driver.find_element(By.XPATH, '//a[@class="layui-layer-btn0" and text()="查看详情"]')
if detail_button:
driver.execute_script("arguments[0].click();", detail_button)
time.sleep(1)
start_study_button = driver.find_element(By.ID, 'startStudy')
driver.execute_script("arguments[0].click();", start_study_button)
return 0
else:
return 1
except:
print("答题失败")
在 第一部分中 StartClass.py
中最后有涉及执行 课程评估,课后测试以及补考代码。
第三部分
从登录开始直接衔接到第一部分播放视频,涉及操作:
- 打开网址
- 点击登录(因为有账号密码的记忆,跳过输入账号密码环节)
- 点击继续登录(因为在不同浏览器登录后,会有校验)
- 点击最新课程中的查看更多(因为要到课程的筛选页面)
- 点击筛选条件:未选课程、课后测试
- 点击下面视频列表中的第一个(选择观看第一个视频)
- 弹出视频详情页面中点击选择课程、点击确认,就会弹出播放视频
- 在OpenEdge.py 最后调用第一部分的
StartClass.py
让脚本衔接起来 - 最后关闭浏览器
打开网址 OpenEdge.py
import subprocess
import time
from selenium import webdriver
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from StartClass import StartClass
import os
import signal
def OpenEdge():
# 启动 Edge 浏览器并附加到远程调试端口
edge_path = "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
edge_process = subprocess.Popen([edge_path, "--remote-debugging-port=9222"])
# 使用 webdriver_manager 自动管理 EdgeDriver 并自动选择合适版本
service = Service(EdgeChromiumDriverManager().install())
# 设置 EdgeOptions 以附加到已有的 Edge 浏览器会话
edge_options = Options()
edge_options.use_chromium = True
edge_options.add_argument("--remote-debugging-port=9222")
# 初始化 WebDriver 使用 service 和 options 参数
driver = webdriver.Edge(service=service, options=edge_options)
# 打开目标网页,需要填入网址,这里我保密
driver.get("")
# 使用显式等待确保登录按钮加载完成
try:
# print("等待登录按钮加载完成...")
login_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//input[@class="login__btn"]'))
)
login_button.click()
print("点击「登录」成功")
except Exception as e:
print(f"点击登录按钮出错:{e}")
time.sleep(1)
# 使用显式等待确保“继续登录”按钮加载完成
try:
# print("等待继续登录按钮加载完成...")
continue_login_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//input[@class="btn-primary" and @onclick="ajaxContinueLogin(this)"]'))
)
continue_login_button.click()
print("点击「继续登录」成功")
except Exception as e:
print("没有「继续登录」按钮,第一次登录")
time.sleep(5)
try:
# 等待页面完全加载
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
iframes = driver.find_elements(By.TAG_NAME, "iframe")
time.sleep(5)
if iframes:
# print(f"找到 {len(iframes)} 个 iframe,尝试切换到每个 iframe 查找元素...")
for iframe in iframes:
driver.switch_to.frame(iframe)
try:
confirm_button = driver.find_element(By.XPATH,'')
driver.execute_script("arguments[0].click();", confirm_button)
print("点击「查看更多」成功")
time.sleep(1)
unselected_courses_label = driver.find_element(By.XPATH,'//label[@class="filter-link " and text()="未选课程"]')
driver.execute_script("arguments[0].click();", unselected_courses_label)
print("点击「未选课程」成功")
time.sleep(1)
test_courses_label = driver.find_element(By.XPATH,'//label[@class="filter-link " and text()="课后测试"]')
driver.execute_script("arguments[0].click();", test_courses_label)
print("点击「课后测试」成功")
time.sleep(1)
searchCourseBody = driver.find_element(By.ID, "searchCourseBody")
ul_element = searchCourseBody.find_element(By.TAG_NAME, "ul")
first_li_element = ul_element.find_element(By.TAG_NAME, "li")
first_li_element.click()
print("选择第一个课程成功")
time.sleep(1)
# 切换回默认内容,避免后续查找操作导致错误
driver.switch_to.default_content()
break
except Exception as e:
print(f"在当前 iframe 中报错: {e}")
driver.switch_to.default_content()
except Exception as e:
print(f"在打开 edge 中报错:{e}")
time.sleep(2)
# 切换窗口句柄
window_handles = driver.window_handles
if window_handles:
driver.switch_to.window(window_handles[1])
print(f"切换到窗口句柄: {driver.title}")
try:
chooseCourse_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, 'chooseCourse'))
)
chooseCourse_button.click()
print("点击「选择课程」成功")
time.sleep(1)
chooseCourse_ok_button = driver.find_element(By.XPATH, '//a[@class="layui-layer-btn0" and text()="确定"]')
driver.execute_script("arguments[0].click();", chooseCourse_ok_button)
print("点击「选择课程确认」成功")
time.sleep(1)
StartClass()
time.sleep(1)
except Exception as e:
print("选择课程出错")
finally:
# 关闭浏览器会话
try:
driver.quit()
except Exception as e:
print(f"关闭浏览器会话时出错: {e}")
# 关闭 Edge 浏览器进程
try:
os.kill(edge_process.pid, signal.SIGTERM)
print("Edge 浏览器进程已关闭")
except Exception as e:
print(f"关闭 Edge 浏览器进程时出错: {e}")
而我们每天最多只能刷5个课程获得积分,所以可以重复 OpenEdge.py
5次
懒得写for循环了,HandOp.py
中也可以在程序出错时,需要手动调用某个方法时使用
重复操作 HandOp.py
from OpenEdge import OpenEdge
from JumpStudy import JumpStudy
from CloseEdge import CloseEdge
import time
OpenEdge()
print("第1次调用结束")
time.sleep(3)
OpenEdge()
print("第2次调用结束")
time.sleep(3)
OpenEdge()
print("第3次调用结束")
time.sleep(3)
OpenEdge()
print("第4次调用结束")
time.sleep(3)
OpenEdge()
print("第5次调用结束")
总结
程序遇到问题
1. 使用固定浏览器版本启动失败
因为浏览器与浏览器驱动版本不对应,改为使用 webdriver_manager 自动管理驱动
2. 使用chrome驱动需要🪜
改为使用 edge 浏览器驱动
3. 页面按钮找不到
按钮未必在页面上写死的,而是在 iframe 中的,比如弹出框。所以在iframe 中查找
# 检查是否在 iframe 中
iframes = driver.find_elements(By.TAG_NAME, "iframe")
if iframes:
# print(f"找到 {len(iframes)} 个 iframe,尝试切换到每个 iframe 查找元素...")
for iframe in iframes:
4. 按钮无法点击
一般我问ai点击事件是:
first_li_element = ul_element.find_element(By.TAG_NAME, "li")
first_li_element.click()
但是部分按钮是js动态加载出来的,需要使用js的方式来点击:
first_li_element = ul_element.find_element(By.TAG_NAME, "li")
driver.execute_script("arguments[0].click();", first_li_element)
5. 无法模仿用户操作
模仿用户操作使用上述的点击事件都不行,后来采用ActionChains
actions = ActionChains(driver)
actions.move_to_element(app_btn).click().perform()
print("模拟用户点击操作")
6. 几率会报找不到元素
可能因为元素还未加载到,可以等待元素加载,我想简单点,直接 time.sleep()
,所以代码中有大量的 sleep ...
7. 直接点击修改后10.0x,视频卡住
原因不好找,尝试直接点击2.0x 没问题,所以先点击2.0x ,过一段时间再点击 10.0x,能解决就行...
潜在问题及优化
1. 网站防自动点击
有些网站通过检测点击时间等方法,做了防爬虫和防自动点击。
优化:点击时间间隔还可以再更改,目前先不动了。
2. 网慢导致卡掉倍速
有时候网慢的时候,更改倍速会失效,还是 1 倍速播放的。
优化:可以在每 5 秒检测下一节、下一步的方法中重复观察倍速状态并点击,目前先不做了,情况很少发生。
3. 屏保到了会锁屏
程序执行时间很长,电脑屏幕保护时间过短的话,会锁屏。
优化:延长屏保时间
4. 自动点击会跳到浏览器
程序每次触发点击事件,如果这会儿在其他程序,电脑会自动跳转到 chrome/edge, 影响当前操作。查询后得知是浏览器的保护措施,保证每次浏览器的操作必须让用户操作。
优化:可以使用无头模式解决,浏览器启动命令增加 --headless
。
但我觉得其实保护措施是对的,我也担心万一有人悄悄改了代码让我不知觉之中做了其他操作...所以这块我先不改动,当不用 edge 的时候,再执行程序,可以肉眼看到程序的自动执行。
最后效果
之后每天休息时间,直接执行 HandOp.py
即可拿到积分,中途有操作失败,也可以更改 HandOp.py
的调用快速解决。
完美实现刷课自动化!
完结撒花!🎉