基于Playwright的智慧树课程自动化学习脚本开发实践

📅 2026/7/23 10:05:42
基于Playwright的智慧树课程自动化学习脚本开发实践
1. 项目概述与核心需求解析最近在技术社群里经常看到有朋友在讨论如何“解放双手”特别是针对一些需要长时间挂机、重复点击的在线学习任务。智慧树作为国内广泛使用的在线课程平台其课程学习通常包含视频观看、章节测验等环节这些环节往往耗时且操作固定。手动完成不仅枯燥还容易因忘记操作而中断学习进度。因此一个能够模拟用户行为、自动完成课程学习的脚本其需求就变得非常具体和迫切。这个项目本质上是一个基于浏览器自动化的“机器人”。它不是为了攻击或破坏系统而是在用户授权和监督下模拟一个真实学习者的操作流程打开浏览器、登录账号、进入课程、播放视频、完成课后习题。其核心价值在于将用户从重复、机械的点击操作中解放出来把时间留给更需要创造性思考和深度学习的环节。当然任何自动化工具的使用都必须严格遵守平台的使用条款本项目的分享旨在探讨Playwright这一现代自动化框架的技术实现供学习者研究参考切勿用于任何违规用途。从技术选型上看之所以选择Python Playwright的组合是因为它几乎是为这类Web自动化任务量身定做的。Python语法简洁生态丰富而Playwright由微软开源支持Chromium、Firefox和WebKit三大浏览器引擎且API设计非常现代和人性化。相比传统的SeleniumPlaywright在自动等待、网络拦截、移动端模拟等方面有着显著优势编写出来的脚本更稳定、更健壮。接下来我将详细拆解这个项目的设计思路、关键实现步骤以及我趟过的那些“坑”。2. 技术选型与环境搭建思路为什么是Playwright这是一个必须首先回答的问题。在Web自动化领域我们有几个常见选择Selenium、Puppeteer和Playwright。Selenium历史悠久生态庞大但配置相对繁琐且对于动态页面的等待处理需要开发者投入更多精力。Puppeteer是Chrome官方团队出品对Chrome/Chromium的支持堪称完美但早期只支持JavaScript且对其他浏览器支持有限。Playwright则可以看作是Puppeteer的“升级版”和“多平台版”。它由原Puppeteer团队的核心成员开发继承了其优良基因并进行了大量改进。其核心优势在于跨浏览器支持一套API可控制Chromium、Firefox和WebKit对于需要测试页面兼容性的场景非常有用。虽然我们这里只针对智慧树通常用Chrome内核访问即可但这意味着技术栈的通用性更强。自动等待这是Playwright最令人称道的特性之一。在定位元素或执行点击前它会自动等待元素达到可操作状态如可见、可点击、稳定等这极大地减少了编写显式等待time.sleep代码的需要让脚本更加稳定。强大的网络控制可以轻松地拦截和修改网络请求这对于处理视频播放心跳、提交答案等场景非常关键。丰富的设备模拟内置了大量移动设备如iPhone、Pixel的视口、User-Agent等参数可以方便地模拟移动端访问。基于以上几点Playwright在开发效率和脚本稳定性上对于此类自动化任务具有明显优势。项目提供了“免安装版”这通常意味着作者已经将Python解释器、Playwright库以及必要的浏览器驱动打包成了一个可执行文件例如使用PyInstaller用户无需配置Python环境即可运行这对非技术用户非常友好。2.1 本地开发环境搭建如果你想自己研究或修改脚本就需要搭建本地开发环境。过程并不复杂。首先你需要安装Python。建议使用Python 3.8及以上版本。可以从Python官网下载安装包安装时务必勾选“Add Python to PATH”这样才能在命令行中直接使用python和pip命令。安装完成后打开命令行CMD或PowerShell通过pip安装Playwright库pip install playwright安装完成后还需要安装Playwright所需的浏览器内核。Playwright提供了一个非常方便的命令来完成这件事playwright install这条命令会下载Chromium、Firefox和WebKit的二进制文件。由于我们主要使用Chromium如果你希望节省时间和磁盘空间可以只安装Chromiumplaywright install chromium至此核心的开发环境就准备好了。你可以创建一个新的Python文件例如zhihuishu_auto.py开始编写代码。注意在某些网络环境下playwright install下载浏览器可能会非常慢甚至失败。这时可以考虑使用镜像源或者在Playwright的配置中指定离线已下载的浏览器路径。不过对于大多数用户耐心等待或切换网络即可。3. 核心功能模块设计与实现拆解一个完整的智慧树刷课脚本可以分解为以下几个核心模块它们串联起来形成了一个完整的自动化工作流。3.1 用户认证与登录模块这是脚本的起点也是最容易出问题的地方之一。智慧树的登录页面可能涉及用户名/密码输入、验证码、甚至滑块验证。实现思路启动浏览器上下文使用Playwright创建一个浏览器实例并建议启用“有头模式”headlessFalse进行初期调试这样你能直观地看到浏览器的操作过程。from playwright.sync_api import sync_playwright with sync_playwright() as p: # 启动Chromium浏览器非无头模式便于调试 browser p.chromium.launch(headlessFalse) # 创建一个新的浏览器上下文类似于一个独立的会话窗口 context browser.new_context() page context.new_page()导航至登录页使用page.goto()方法打开智慧树登录页面。填充登录信息定位用户名和密码输入框。这里就需要用到Playwright的定位器Locator。智慧树的页面结构可能会变所以需要通过浏览器开发者工具F12来查看当前输入框的HTML属性如id、class、name等。# 假设通过查看元素发现用户名输入框的id是‘lUsername’ page.locator(#lUsername).fill(你的学号) page.locator(#lPassword).fill(你的密码)处理验证码这是难点。如果遇到图形验证码简单的自动化脚本很难识别。可能的解决方案有手动介入在脚本中设置一个等待提示用户手动输入验证码后再继续。第三方OCR服务接入付费或免费的OCR API进行识别但这会增加复杂性和成本。观察规律有些网站的验证码在短时间内同一IP或会话下不会频繁更换可以尝试先手动登录一次脚本保存cookies后续使用cookies恢复会话来跳过登录。Playwright的context.storage_state()方法可以非常方便地保存和加载cookies及本地存储。# 首次手动登录后保存状态 context.storage_state(pathstate.json) # 下次运行脚本时直接加载状态可能无需再次登录 context browser.new_context(storage_statestate.json) page context.new_page() page.goto(https://passport.zhihuishu.com/) # 直接跳转已登录后的页面实操心得强烈推荐使用“保存登录状态”的方式。首次运行脚本时用headlessFalse模式手动完成登录包括处理任何验证码然后让脚本保存状态文件。之后运行脚本时直接加载这个状态文件绝大多数情况下都可以直接进入已登录状态完美绕过登录难题。3.2 课程导航与章节遍历模块登录成功后脚本需要找到目标课程并进入学习界面。智慧树的课程列表通常在一个“我的课程”或“学习空间”页面。实现思路等待页面加载登录后跳转的页面可能是一个门户需要等待关键元素如“我的课程”链接出现。使用Playwright的page.wait_for_selector()或直接使用Locator的wait_for()方法。# 等待“我的课程”这个元素出现假设它是一个链接文本内容是“我的课程” page.locator(text我的课程).wait_for() page.locator(text我的课程).click()定位目标课程课程列表可能是动态加载的。需要找到包含目标课程名称的元素并点击。这里定位器的文本匹配功能非常有用。# 点击课程名为“大学计算机基础”的课程卡片 page.locator(text大学计算机基础).click()进入学习进度页面进入课程后通常需要点击“学习进度”或类似的标签页才能看到章节列表。遍历章节章节列表通常是一个树形结构或列表。需要编写逻辑来遍历每一个章节或单元。可以使用page.locator()获取所有章节项的列表然后循环处理。# 假设每个章节项都有一个共同的类名 ‘chapter-item’ chapter_items page.locator(.chapter-item) count chapter_items.count() for i in range(count): item chapter_items.nth(i) # 点击展开或进入章节 item.click() # 这里开始处理该章节下的视频和测验 # ... # 处理完后可能需要返回章节列表页或者页面本身就在当前章节内注意事项页面操作如点击章节可能会触发动态加载或页面跳转。务必在关键操作后使用page.wait_for_load_state(networkidle)或等待特定元素出现确保页面稳定后再进行下一步操作这是脚本稳定性的关键。3.3 视频播放与进度监控模块这是刷课的核心。脚本需要自动播放视频并确保视频计时进度被系统正确记录。实现思路定位视频播放器进入具体章节后找到视频播放器。它可能是一个video标签也可能是基于Flash或H5的播放器。现代网站大多使用HTML5的video标签。控制播放Playwright可以直接与video标签交互。# 定位到video元素 video page.locator(video) # 点击播放按钮如果视频没有自动播放 video.click() # 或者通过执行JS来播放 page.evaluate(document.querySelector(video).play())监控进度与心跳仅仅播放视频是不够的。智慧树后台通常会有“心跳”机制定期向服务器报告学习进度以防止纯粹的前端播放作弊。我们需要模拟这个行为。网络监听法推荐使用Playwright的page.on(request)事件监听器捕获浏览器发出的所有网络请求。通过分析找到那个周期性发送的、包含进度信息的“心跳”请求通常是一个POST请求URL包含heartBeat或report等关键词。一旦找到我们可以确保这个请求被正常发出或者甚至可以直接用脚本模拟发送这个请求。def handle_request(request): if heartBeat in request.url: print(f捕获到心跳请求: {request.url}) # 可以在这里记录或不做处理确保请求正常发出即可 page.on(request, handle_request)进度模拟法如果找不到明确的心跳请求可能需要模拟用户与视频的交互如随机移动鼠标、轻微滚动页面等让页面脚本认为用户正在活动。处理弹题视频播放过程中可能会弹出随堂问题。脚本需要检测这些弹窗并选择答案。# 监听弹题窗口的出现假设弹题窗口有一个特定的类名 ‘popup-quiz’ try: quiz_popup page.locator(.popup-quiz).wait_for(timeout5000) # 等待5秒看是否出现 # 如果出现了选择第一个答案或根据逻辑选择 quiz_popup.locator(.answer-option).first.click() quiz_popup.locator(.submit-btn).click() except: # 没有弹题继续 pass实操心得视频播放部分最关键的挑战是“防作弊机制”。单纯的前端播放很容易被系统检测并判定为无效学习。通过网络请求监听来确保后台心跳的正常发送是最有效、最接近真实用户行为的方式。务必花时间分析智慧树学习时的网络请求找到那个关键的心跳接口。3.4 章节测验自动答题模块完成视频学习后通常会有章节测验。自动化答题的复杂度取决于题目的类型。实现思路进入测验页面点击“章节测验”或“去做题”按钮。获取题目与选项解析页面结构提取题目文本和所有选项。这需要仔细分析测验页面的HTML。# 假设每个题目都包裹在一个类名为 ‘question-item’ 的div中 questions page.locator(.question-item) for i in range(questions.count()): q questions.nth(i) question_text q.locator(.question-stem).inner_text() options q.locator(.option-item) # 接下来需要根据题目文本决定如何选择答案答题策略固定答案如果题库固定可以建立本地题库映射题目文本 - 答案。搜索答案将题目文本提取出来通过浏览器打开一个新的标签页使用搜索引擎如百度进行搜索然后从搜索结果中提取最可能的答案。这涉及到更复杂的多页面控制和文本解析。随机选择对于选择题在没有更好策略时随机选择一个选项。但这正确率低。OCR识别针对图片题极少情况题目可能是图片需要集成OCR功能。提交答案所有题目处理完毕后点击提交按钮。并处理提交后的结果如确认对话框。page.locator(text提交答案).click() # 处理可能的确认弹窗 page.on(dialog, lambda dialog: dialog.accept())注意事项自动答题是脚本中风险较高的部分因为可能涉及平台规则。且智慧树的题目可能更新导致固定题库失效。搜索答案的策略虽然智能但速度慢且依赖于外部网络。请谨慎使用此功能并优先考虑用于学习研究目的。4. 脚本的健壮性处理与错误恢复一个能长时间稳定运行的脚本必须考虑各种异常情况。4.1 元素定位失败处理页面加载慢、元素动态生成都可能导致定位失败。不能使用固定的sleep而应利用Playwright的自动等待和显式等待。from playwright.sync_api import TimeoutError as PlaywrightTimeoutError try: # 显式等待某个关键元素最多10秒 element page.locator(#critical-button).wait_for(timeout10000) element.click() except PlaywrightTimeoutError: print(关键元素未在指定时间内出现可能页面加载异常。) # 错误恢复策略刷新页面或者记录错误并跳过当前任务 page.reload() # 或者 break/continue 到下一个循环4.2 网络异常与页面崩溃处理脚本运行中可能遇到网络断开、页面崩溃特别是长时间运行。# 监听页面崩溃事件 page.on(close, lambda: print(页面意外关闭)) # 在实际操作中可能需要将大的任务如一门课分解成小任务 # 并定期保存进度如当前处理到的章节索引以便崩溃后能从断点恢复。4.3 登录状态失效处理虽然使用了保存的状态但登录会话可能过期。脚本需要检测是否被重定向到了登录页。# 在执行某个操作前检查当前页面是否还在登录状态 if login in page.url or page.locator(text登录).is_visible(): print(检测到登录状态失效尝试重新登录...) # 调用重新登录的函数或者提示用户手动干预 relogin(page)5. 免安装版封装与使用指南对于不会Python环境的用户“免安装版”极大地降低了使用门槛。这通常是通过PyInstaller或cx_Freeze等工具将Python脚本及其所有依赖包括Python解释器打包成一个独立的可执行文件.exe。封装关键步骤确保你的脚本在开发环境下运行无误。安装PyInstallerpip install pyinstaller执行打包命令。一个典型的命令如下pyinstaller --onefile --add-data state.json;. --hidden-import playwright._impl._pywheel zhihuishu_auto.py--onefile打包成单个exe文件。--add-data将非代码文件如保存登录状态的state.json打包进去。--hidden-import确保Playwright的一些隐式依赖被包含。打包完成后在dist目录下会生成exe文件。这个文件可以复制到任何Windows电脑上运行无需安装Python。给最终用户的使用指南首次运行双击exe文件会弹出一个命令行窗口和浏览器窗口。请勿关闭命令行窗口。在浏览器中手动完成智慧树登录如果需要验证码请手动输入。登录成功、页面跳转到课程列表后脚本通常会开始自动工作或者按某个键如回车开始。首次运行后脚本会在同级目录下生成一个state.json文件保存了你的登录会话。后续运行只要state.json存在且登录未过期再次运行exe时脚本会直接使用保存的会话无需再次手动登录。注意事项运行期间请保持电脑不休眠、不断网。关闭浏览器窗口或命令行窗口脚本即停止。重要提醒使用任何自动化脚本都存在一定风险。智慧树平台用户协议中通常禁止任何形式的自动化程序访问。使用此类脚本可能导致学习记录被判定无效、账号受到限制等后果。本技术分享仅供学习和研究浏览器自动化技术之用请务必谨慎评估使用风险尊重平台规则。6. 进阶优化与扩展思考在实现了基本功能后还可以从以下几个方面进行优化配置化将账号、密码、目标课程名、学习速度播放速率等参数提取到外部的配置文件如config.ini或config.json中避免硬编码。多账号与并发使用Playwright的多个Browser Context可以在同一个浏览器实例内实现多账号同时运行相互隔离cookies。但这对电脑性能要求较高且平台风控风险急剧增加不推荐普通用户尝试。图形用户界面GUI使用tkinter、PyQt或DearPyGui为脚本制作一个简单的图形界面方便用户输入参数、查看运行日志和进度。更智能的答题策略集成一个轻量级的本地向量数据库如SQLite文本嵌入将题目和答案存储起来实现更高效、更准确的题库匹配。日志与监控完善日志系统记录脚本运行的每一步包括成功、失败、遇到的异常等方便后期排查问题。浏览器自动化是一个强大的工具Playwright使得这一过程变得更加高效和可靠。通过这个项目我们不仅解决了一个具体问题更深入学习了现代Web自动化测试与爬虫的核心技术。记住技术是把双刃剑始终用在正当、合规的地方才是长久之道。