利用Selenium实现安全微伴课程自动化学习:解放双手的编程实践
1. 为什么需要自动化学习工具
作为一个经常需要上网课的学生,我深刻理解那种重复点击"下一步"的痛苦。每次打开安全微伴的课程页面,都要机械式地完成视频播放、章节测试、答题验证等操作,不仅浪费时间,还容易让人分心。特别是当课程数量多、内容枯燥时,这种重复劳动简直是对意志力的考验。
程序员的天性就是寻找自动化解决方案。既然这些操作都是固定流程,为什么不让程序帮我们完成呢?Selenium作为最流行的Web自动化测试工具,恰好能完美解决这个问题。它就像一双无形的手,可以模拟人类的所有浏览器操作:点击按钮、填写表单、跳转页面等等。我去年第一次用Selenium自动完成网课时,看着浏览器自动跳转页面的感觉,就像是拥有了一个24小时工作的学习助手。
不过要提醒的是,自动化工具应该用在正当的学习场景。比如你确实需要完成这些课程,只是希望节省机械操作的时间。如果单纯为了刷课而刷课,那就失去了学习的意义。我在实际使用中,通常会设置自动化程序只完成基础操作环节,重要的知识点还是会亲自学习。
2. 环境准备与基础配置
2.1 安装Python和Selenium
工欲善其事,必先利其器。首先需要安装Python环境,建议使用3.7以上版本。我习惯用Anaconda来管理Python环境,这样可以避免各种依赖冲突。安装完成后,通过pip安装Selenium包非常简单:
pip install selenium如果你遇到网络问题,可以尝试使用国内镜像源:
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple2.2 浏览器驱动配置
Selenium需要浏览器驱动才能工作。以Edge浏览器为例,首先查看你的浏览器版本(在地址栏输入edge://version/),然后到Microsoft的开发者网站下载对应版本的驱动。这里有个小技巧:我建议把驱动文件放在项目目录下,这样就不需要配置系统PATH了。
下载完成后,可以写个简单的测试脚本验证是否配置成功:
from selenium import webdriver driver = webdriver.Edge(executable_path='./msedgedriver.exe') driver.get("https://www.baidu.com") print(driver.title) driver.quit()如果能看到浏览器自动打开并显示百度首页,说明环境配置正确。我在第一次配置时遇到过驱动版本不匹配的问题,这时候只需要确保浏览器和驱动版本完全一致即可。
3. 安全微伴页面元素定位
3.1 登录流程自动化
安全微伴的登录方式通常是微信扫码。通过分析登录流程,我发现它的二维码是通过API动态生成的。我们可以用requests库获取二维码图片,然后用OpenCV显示出来:
import requests import cv2 login_url = "https://weiban.mycourse.cn/pharos/login/genBarCodeImageAndCacheUuid.do" response = requests.get(login_url).json() image_url = response['data']['imagePath'] # 显示二维码 img = cv2.imread(image_url) cv2.imshow("请扫码登录", img) cv2.waitKey(0)扫码登录后,系统会返回token等认证信息,这些需要保存下来供后续请求使用。我在这里踩过一个坑:token有过期时间,长时间运行的程序需要处理会话过期的异常。
3.2 课程页面结构分析
安全微伴的课程页面主要分为三个部分:左侧的章节列表、中间的课程内容区域和顶部的进度显示。通过浏览器开发者工具(F12),可以查看各个元素的CSS选择器:
- 章节列表:
.folder-list > .folder-item - 课程项目:
.course-list > li - 进度显示:
.progress-percent
在实际操作中,我发现页面加载需要时间,所以必须合理设置等待。Selenium提供了两种等待方式:显式等待和隐式等待。我的经验是混合使用:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待章节列表加载 chapters = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".folder-list > .folder-item")) )4. 核心自动化逻辑实现
4.1 课程完成算法设计
安全微伴的课程完成逻辑其实很简单:找到未完成的课程,执行完成操作。但实际实现时需要考虑很多边界情况:
- 课程可能已经完成
- 网络延迟导致元素未加载
- 弹出框干扰正常流程
- 页面iframe嵌套结构
我的解决方案是分步骤处理:
def complete_course(driver): # 1. 进入章节 chapter = find_unfinished_chapter() chapter.find_element(By.CSS_SELECTOR, "div.folder-extra > a.btn").click() # 2. 获取第一个课程 course = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".course-list > li:nth-child(1)")) ) # 3. 检查是否已完成 if course.find_elements(By.CSS_SELECTOR, "h3 > i"): return True # 4. 进入课程iframe course.click() WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe.page-iframe")) ) # 5. 执行完成脚本 driver.execute_script("finishWxCourse()") driver.switch_to.alert.accept() # 6. 返回主框架 driver.switch_to.default_content() return False4.2 异常处理与重试机制
网络环境不稳定时,程序很容易因为元素找不到而崩溃。我通过添加重试机制提高了稳定性:
def safe_click(element, max_retries=3): for i in range(max_retries): try: element.click() return True except Exception as e: print(f"点击失败,重试 {i+1}/{max_retries}") time.sleep(2) return False对于页面跳转这类操作,我还添加了超时判断:
from selenium.common.exceptions import TimeoutException try: WebDriverWait(driver, 10).until( EC.url_contains("course") ) except TimeoutException: print("页面跳转超时") driver.refresh()5. 完整项目优化建议
5.1 配置化设计
把课程URL、登录信息等配置项提取出来,方便不同场景使用:
config = { "base_url": "https://weiban.mycourse.cn", "course_params": { "projectId": "12345", "projectType": "special" }, "wait_timeout": 10 }5.2 日志记录与进度保存
添加日志功能可以方便调试和查看运行状态:
import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('auto_learn.log'), logging.StreamHandler() ] )对于长时间运行的脚本,建议定期保存进度:
import json def save_progress(progress): with open('progress.json', 'w') as f: json.dump(progress, f) def load_progress(): try: with open('progress.json', 'r') as f: return json.load(f) except FileNotFoundError: return {}5.3 性能优化技巧
经过多次实践,我总结出几个提升效率的方法:
- 复用浏览器会话:不要每次操作都重新打开浏览器
- 并行处理多个课程:使用多线程加速
- 减少不必要的等待:根据网络状况动态调整等待时间
- 禁用图片加载:提升页面加载速度
# 浏览器性能优化选项 options = webdriver.EdgeOptions() options.add_argument('--blink-settings=imagesEnabled=false') driver = webdriver.Edge(options=options)这些优化让我的脚本运行时间从原来的30分钟缩短到了10分钟左右。当然,具体效果取决于你的网络环境和课程数量。
