Python自动化评教脚本:从HTTP会话到CSRF令牌的完整实现
1. 从手动到自动评教这件事为什么值得“折腾”每到学期末高校里总会上演一出“评教大戏”。学生们被要求在教务系统里对每一位任课老师进行打分和评价。这事儿听起来简单但实际操作起来却是个不折不扣的“体力活”。想象一下一个学生要面对十几门课程每门课的评价体系可能包含几十个评分项和主观题全部填完少说也得花上半小时。更别提那些需要反复登录、页面卡顿、提交失败的“常规操作”了。对于学生来说这成了期末复习之外的又一重负担对于学校而言评教数据的回收率、有效性和真实性也常常因此大打折扣。于是“教务系统自动评教”这个想法就在这种背景下应运而生了。它本质上是一个自动化脚本旨在模拟人工操作自动完成登录教务系统、选择课程、填写评价表单、提交结果这一系列流程。这听起来有点像“外挂”但其初衷并非为了作弊或破坏规则而是为了解决一个真实存在的效率痛点。很多同学开发这类脚本最初的想法很简单把时间从重复、机械的点击和填写中解放出来去做更有价值的事情比如复习备考。当然这里必须强调任何自动化工具的使用都必须严格遵守学校的相关规定不得用于恶意刷分或干扰正常教学秩序。本文探讨的技术实现更多是作为一种编程学习和自动化流程设计的案例。从技术角度看实现一个自动评教脚本会涉及到几个核心领域网络请求的模拟HTTP/HTTPS、网页数据的解析HTML/DOM、表单的自动填充与提交以及可能遇到的验证码识别、登录状态维持等反自动化对抗措施。这不仅仅是一个简单的“按键精灵”它要求开发者对Web前端与后端的交互逻辑有清晰的理解。接下来我将以一个典型的、基于Python的自动化方案为例手把手拆解其实现原理、核心步骤以及那些“踩过才知道”的坑。2. 核心原理拆解浏览器在背后都干了些什么在动手写代码之前我们必须先搞清楚当我们在浏览器里手动评教时到底发生了什么。这个过程就是我们编写脚本需要精准模拟的“剧本”。2.1 会话Session与Cookie你的“临时身份证”当你第一次输入学号和密码登录教务系统时服务器验证通过后会生成一个唯一的“会话标识”Session ID并通过响应头中的Set-Cookie字段发送给你的浏览器。浏览器会保存这个Cookie。此后你在该网站内的每一次点击、跳转、提交表单浏览器都会自动在请求头中带上这个Cookie通常是Cookie: JSESSIONIDxxxxxx。服务器通过这个Cookie来识别“哦是刚才那个已经登录的用户”。这就是HTTP协议无状态特性下维持用户登录状态的核心机制。注意我们的自动化脚本必须完整地模拟这一过程。这意味着不能只模拟一次登录请求就完事必须在后续的所有请求中手动维护并携带这个关键的Cookie。在Python的requests库中使用Session对象可以非常方便地做到这一点它会自动处理Cookie的存储和发送。2.2 表单提交与CSRF令牌防止“跨站攻击”的盾牌现代教务系统为了安全几乎都会使用CSRF跨站请求伪造令牌。你会发现评教页面的表单里除了你看得见的评分选项和文本框往往还藏着一个或多个名为_csrf、csrf_token或类似名称的隐藏输入框input typehidden ...。它的值是一串随机字符串。这个令牌是服务器在生成表单页面时动态创建的。当你提交表单时必须将这个令牌原封不动地随表单数据一起提交。服务器会校验你提交的令牌是否与它之前发给你的那个匹配。如果不匹配请求会被直接拒绝。这有效防止了恶意网站伪造你的身份提交表单。对于自动化脚本来说这意味着一个关键步骤在提交评教数据前必须先访问评教页面从HTML源码中把这个隐藏的CSRF令牌值“挖”出来。我们通常使用像BeautifulSoup或lxml这样的HTML解析库来完成这项工作。2.3 请求的观察与分析开发者工具是“眼睛”所有上述信息——登录的API地址、提交评教的URL、需要提交的表单字段名、CSRF令牌的位置——都需要我们通过浏览器的开发者工具按F12打开来观察和获取。具体操作流程如下登录过程打开教务系统登录页在开发者工具的“网络”Network选项卡中勾选“保留日志”Preserve log。然后手动输入账号密码登录。在网络请求列表中你会看到登录时产生的一系列请求。找到那个POST类型的、看起来是提交登录信息的请求通常URL包含login、doLogin等关键词。点击这个请求查看其“标头”Headers和“负载”Payload。这里记录了请求的URL、方法POST、以及提交的表单数据如username你的学号password加密后的密码。评教过程登录后进入评教页面。同样观察网络请求找到加载评教表单的那个GET请求查看其响应内容找到CSRF令牌。然后手动选择评分、填写意见点击提交。再次观察网络请求找到提交评教的那个POST请求查看其提交的数据格式。你会发现数据通常是一个键值对集合键名对应前端的name属性值就是你选择的分数或填写的文字。只有通过这样细致的观察我们才能编写出能精准模拟人工操作的脚本。不同学校的教务系统如强智、清元优软、金智等接口和字段名可能完全不同但分析方法是通用的。3. 实战构建一个Python自动评教脚本的诞生基于以上原理我们可以开始构建脚本。这里我选择Python因为它拥有极其丰富和强大的网络请求与解析库。核心工具是requests处理HTTP请求和BeautifulSoup解析HTML。3.1 环境准备与基础架构首先安装必要的库pip install requests beautifulsoup4脚本的基础骨架如下import requests from bs4 import BeautifulSoup import time class AutoEvaluation: def __init__(self, base_url, username, password): self.base_url base_url.rstrip(/) # 教务系统基础URL如 http://jwxt.xxx.edu.cn self.username username self.password password self.session requests.Session() # 创建会话对象自动管理Cookie self.session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 }) # 设置一个常见的浏览器UA避免被简单屏蔽 def login(self): 模拟登录流程 # 1. 首先访问登录页可能获取登录所需的初始token或验证码信息 login_page_url f{self.base_url}/login.jsp resp self.session.get(login_page_url) # 这里可能需要解析页面中的隐藏token具体看学校系统 # soup BeautifulSoup(resp.text, html.parser) # token soup.find(input, {name: lt})[value] # 举例 # 2. 构造登录数据并提交 login_api_url f{self.base_url}/doLogin.action # 登录接口需根据实际情况修改 login_data { username: self.username, password: self.password, # lt: token, # 如果有的话 # execution: e1s1, # _eventId: submit } login_resp self.session.post(login_api_url, datalogin_data) # 3. 验证登录是否成功简单方法检查响应内容或后续访问个人页面 if 用户名或密码错误 in login_resp.text: print(登录失败请检查账号密码。) return False print(登录成功) return True def get_evaluation_list(self): 获取待评教课程列表 # 访问评教入口页面 eval_entry_url f{self.base_url}/evaluation/toEvaluation.action resp self.session.get(eval_entry_url) soup BeautifulSoup(resp.text, html.parser) # 解析课程列表通常在一个table或ul列表中 course_list [] # 假设课程链接在 class 为 eval-course 的a标签里 for link in soup.select(a.eval-course): course_name link.text.strip() course_url link[href] # 处理相对URL if course_url.startswith(/): course_url self.base_url course_url course_list.append({name: course_name, url: course_url}) print(f找到 {len(course_list)} 门待评教课程。) return course_list def evaluate_course(self, course_info): 对一门课程进行自动评教 course_url course_info[url] print(f开始评教课程{course_info[name]}) # 1. 访问课程评教页面获取表单和CSRF令牌 resp self.session.get(course_url) soup BeautifulSoup(resp.text, html.parser) # 查找CSRF令牌 csrf_token_elem soup.find(input, {name: _csrf}) # 名称可能不同 if not csrf_token_elem: # 尝试其他常见名称 csrf_token_elem soup.find(input, {name: csrfToken}) or soup.find(input, {name: token}) if csrf_token_elem: csrf_token csrf_token_elem[value] else: csrf_token print(警告未找到CSRF令牌可能评教失败。) # 2. 解析评教表单的所有评分项 # 假设评分项是radio inputname类似 score1, score2... form_data {} if csrf_token: form_data[_csrf] csrf_token # 模拟填写这里我们假设对所有评分项都选择最高分例如5分 # 你需要根据实际页面的input名称来修改 for i in range(1, 11): # 假设有10个评分项 radio_name fscore{i} radio_input soup.find(input, {name: radio_name, value: 5}) # 找值为5的选项 if radio_input: form_data[radio_name] 5 else: # 可能是下拉菜单或其他形式需要具体分析 pass # 填写主观评价可选 comment_box soup.find(textarea, {name: suggestion}) if comment_box: form_data[suggestion] 老师讲课认真内容丰富受益匪浅。 # 通用好评 # 3. 找到表单提交的URL和方式 form_elem soup.find(form, idevalForm) or soup.find(form) # 找到评教表单 if not form_elem: print(未找到评教表单跳过该课程。) return False submit_url form_elem.get(action) if submit_url.startswith(/): submit_url self.base_url submit_url elif not submit_url.startswith(http): # 处理相对路径 submit_url course_url.rsplit(/, 1)[0] / submit_url # 4. 提交评教数据 submit_resp self.session.post(submit_url, dataform_data) if 评教成功 in submit_resp.text or 提交成功 in submit_resp.text: print(f课程 [{course_info[name]}] 评教成功) return True else: print(f课程 [{course_info[name]}] 评教可能失败请检查。) # 可以保存响应文本用于调试 # with open(error.html, w, encodingutf-8) as f: # f.write(submit_resp.text) return False def run(self): 主运行流程 if not self.login(): return time.sleep(1) # 等待一下模拟人工操作间隔 courses self.get_evaluation_list() for course in courses: self.evaluate_course(course) time.sleep(2) # 每评一门课间隔2秒避免请求过快被服务器限制 if __name__ __main__: # 使用时替换为你的实际信息 BASE_URL http://jwxt.yourschool.edu.cn USERNAME 你的学号 PASSWORD 你的密码 evaluator AutoEvaluation(BASE_URL, USERNAME, PASSWORD) evaluator.run()这是一个高度简化的框架实际学校的系统要复杂得多。但它清晰地展示了核心流程创建会话 - 登录 - 获取课程列表 - 循环处理每门课程获取令牌、构造数据、提交。3.2 关键环节的深度剖析与适配上面的框架代码中有几个关键点需要根据实际情况进行深度适配这也是最容易出问题的地方。1. 密码的加密与编码很多教务系统不会明文传输密码。你需要在开发者工具中仔细观察登录请求的“负载”Payload。密码字段password的值可能是一串看似乱码的字符串。这通常是前端JavaScript进行了加密如MD5、SHA1、BASE64或自定义算法。我们的脚本必须模拟同样的加密过程。解决方法有两种方法A推荐找到前端加密的JS代码用Python实现相同的加密逻辑。这需要一定的JavaScript逆向能力。方法B取巧如果加密不是强随机性的比如只是简单的MD5你可以先手动登录一次从开发者工具中复制出加密后的密码字符串直接硬编码到脚本里。但注意如果密码加密使用了随机盐salt此方法失效。2. 动态加载的课程列表有些系统的评教课程列表不是直接写在HTML里而是通过Ajax异步加载的JSON格式。这时get_evaluation_list方法就不能再解析HTML了而需要找到那个加载列表数据的API接口通常在“网络”选项卡中看到一个返回JSON的XHR请求然后直接用session.get()或session.post()去请求这个接口解析返回的JSON数据。3. 复杂表单结构与评分逻辑评分表可能非常复杂有单选、多选、滑块、矩阵量表多个题目共用一套选项。你需要仔细分析每个评分项对应的HTML元素。例如矩阵量表中每个问题的选项可能name相同但value不同或者通过name中的下标来区分。构造form_data字典时必须确保键值对与浏览器提交的完全一致。一个有效的调试方法是先用脚本打印出解析到的所有input/select/textarea的name和value然后手动在浏览器提交一次对比网络请求中的表单数据查漏补缺。4. 验证码CAPTCHA的识别这是自动化最大的拦路虎。如果登录或评教环节有验证码脚本的复杂度将急剧上升。处理方案有人工介入在需要验证码时脚本暂停将验证码图片下载到本地或显示出来等待用户手动输入然后继续执行。OCR识别使用开源的OCR库如ddddocr、pytesseract进行识别但对付扭曲、干扰线多的验证码效果不佳。打码平台调用第三方付费打码API由人工平台协助识别可靠性高但有成本。绕过策略观察验证码是否在同一个会话中会重复使用或者是否有其他无需验证码的备用接口可能性极低。4. 进阶挑战与反自动化对抗策略当你以为脚本可以完美运行时很可能会遇到以下问题这都是教务系统为了阻止自动化操作而设置的“路障”。4.1 请求频率限制与行为检测服务器可能会监控异常请求。如果你的脚本以极快的速度比如每秒数次连续提交评教很可能会触发风控导致IP被临时封锁或会话失效。应对策略增加随机延迟在关键操作如登录后、访问每个课程页面前、提交后使用time.sleep()增加等待时间并且延迟时间最好在一定范围内随机如time.sleep(random.uniform(1, 3))模拟人的操作间隔。模拟更真实的浏览行为在访问评教页面之前可以先随机访问几个其他页面如成绩查询、课表页面让请求序列看起来更“自然”。使用代理IP池如果IP被封锁可以考虑使用代理IP。但对于个人评教而言通常不需要如此复杂。4.2 前端JavaScript动态计算参数有些系统会在提交前通过JavaScript动态计算一些参数并添加到表单中比如时间戳的哈希值、鼠标移动轨迹的加密值等。这些值单纯通过解析静态HTML是获取不到的。应对策略使用无头浏览器这是解决复杂动态网页自动化的终极方案。工具如Selenium、Playwright或Puppeteer可以控制一个真实的浏览器如Chrome来加载页面、执行JavaScript、模拟点击和输入。它能完美处理所有前端动态生成的内容。缺点是运行速度慢、资源占用高。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 driver webdriver.Chrome() driver.get(login_url) driver.find_element(By.ID, username).send_keys(username) driver.find_element(By.ID, password).send_keys(password) driver.find_element(By.ID, submitBtn).click() # ... 后续操作使用无头浏览器时同样需要注意延迟和避免检测有些网站会检测webdriver属性。4.3 登录状态丢失与异常处理网络波动、服务器错误、会话超时都可能导致脚本运行中断。一个健壮的脚本必须有完善的异常处理和状态检查。应对策略加入重试机制对于网络请求使用try...except包裹并在失败后重试几次。定期检查登录状态在评教几个课程后可以访问一下“个人中心”页面检查页面内容是否包含用户名以此判断会话是否依然有效。如果失效则需要重新调用login()方法。详细的日志记录将每一步操作、遇到的异常、服务器返回的关键信息都记录到日志文件或控制台便于出错时排查。5. 伦理、风险与最佳实践在技术实现的兴奋之余我们必须冷静地讨论使用自动评教脚本的边界。1. 遵守规则是第一前提务必仔细阅读你所在学校关于教务系统使用的管理规定。明确禁止自动化操作的系统切勿使用脚本以免触犯校规导致账号被封禁甚至更严重的处分。本文的技术分享仅用于学习和研究HTTP协议、Web自动化以及Python编程请勿用于任何违规用途。2. 评教数据的真实性与价值评教的根本目的是帮助老师改进教学、让学校了解教学情况。全部打满分或随意填写的自动化评教产出的数据是无效甚至有害的扭曲了真实的反馈。即使使用脚本也建议在关键的主观评价部分根据课程实际情况进行手动填写或者至少设置一个合理的、有波动的评分逻辑而不是千篇一律的满分。3. 脚本的保管与使用此类脚本包含了你的学号和密码即使经过加密处理。务必妥善保管代码不要上传到公开的代码仓库如GitHub以免个人信息泄露。可以在代码中通过读取环境变量或外部配置文件的方式来传入敏感信息。4. 一个折中的“半自动”方案如果你希望节省时间又希望保留一定的真实性可以考虑“半自动”方案让脚本自动完成登录、跳转到每门课的评教页面、并自动填充好所有固定的客观题评分例如都填“非常同意”然后暂停弹出主观题输入框让你手动填写意见或者让你快速检查一下客观题评分是否需要微调确认后再由脚本提交。这样既提升了效率又保证了核心反馈的真实性。实现这样一个自动评教脚本是一个绝佳的Web逆向工程和自动化实战项目。它迫使你去理解HTTP协议、会话管理、前端与后端的交互、反爬虫策略等一整套知识。无论最终你是否用它来“偷懒”这个构建过程本身带来的技术提升都是实实在在的。在动手的过程中你遇到的每一个错误、解决的每一个问题都是比单纯使用脚本更宝贵的经验。

相关新闻

跨境电商智能化实战:AI如何赋能客服自动回复、广告智能投放与供应链预测

跨境电商智能化实战:AI如何赋能客服自动回复、广告智能投放与供应链预测

一、引言:从“降本”到“重构” 2026年,AI在跨境电商领域已不再是“要不要用”的问题,而是“用到什么程度”的问题。数据显示,目前已有60%至70%的中国出海商户在不同程度上接入了AI技术,行业正加速迎来“技术平权”时代…

2026/10/15 19:22:51 阅读更多 →
Python网络爬虫权威指南:从环境搭建到Scrapy框架的工程化学习路径

Python网络爬虫权威指南:从环境搭建到Scrapy框架的工程化学习路径

这类工具最值得先看的不是功能列表,而是能不能在普通环境里稳定跑起来。对于想系统学习网络爬虫,特别是想从零开始、避免在零散教程里迷失方向的人来说,找到一本结构清晰、内容权威、能带你从环境搭建到实战落地的“地图”至关重要。很多人学…

2026/10/1 6:33:38 阅读更多 →
数字孪生体:从概念到产业落地的核心引擎与实战剖析

数字孪生体:从概念到产业落地的核心引擎与实战剖析

1. 数字孪生体:从概念到产业落地的核心引擎 最近几年,无论是制造业的工厂车间,还是智慧城市的指挥中心,“数字孪生体”这个词的出现频率越来越高。它不再是实验室里的前沿概念,而是实实在在地走进了各行各业&#xff0…

2026/10/14 4:19:00 阅读更多 →

最新新闻

Unity第三人称摄像机系统:防穿墙、遮挡响应与动态锚点实现

Unity第三人称摄像机系统:防穿墙、遮挡响应与动态锚点实现

1. 为什么“第三人称视角”在Unity里从来不是个简单开关很多人刚接触Unity的第三人称项目时,第一反应是:“不就是把摄像机挂在角色后面,再加个鼠标拖拽旋转?Unity Asset Store里随便下个Cinemachine模板不就完事了?”—…

2026/10/16 7:18:05 阅读更多 →
短剧出海App全球化解决方案:本土化、技术适配与合规实践

短剧出海App全球化解决方案:本土化、技术适配与合规实践

这两年身边做内容的团队几乎都在聊短剧出海,我自己也完整走过一轮从立项、上线、踩坑到逐步跑通的全过程。回头看,这个赛道真正考验人的不是“能不能做出一部爆款短剧”,而是“出海短剧App全球化解决方案”里三个最容易被糊弄过去的维度——本…

2026/10/16 7:18:05 阅读更多 →
告别Arduino IDE:用arduino-builder命令行编译与CI集成实战

告别Arduino IDE:用arduino-builder命令行编译与CI集成实战

简介:arduino-builder 是一款用 Go 语言编写的 Arduino 草图命令行编译工具,面向需要在无 IDE 环境下构建、集成或自动化编译 Arduino 项目的开发者与工具链维护者。它能够解析草图结构、自动生成函数原型、收集库路径并调用 gcc 完成编译,弥…

2026/10/16 7:18:05 阅读更多 →
线程池原理与参数配置实战:从核心机制到生产落地

线程池原理与参数配置实战:从核心机制到生产落地

先聊点实际的。线程池这仨字,搞 Java 的人几乎天天见,面试背八股要背,线上排查故障要查,但真正能把原理讲清楚、又能把参数填对的人,我遇到的真不多。我见过太多团队直接把 newFixedThreadPool(10) 往代码里一扔&#…

2026/10/16 7:18:05 阅读更多 →
Windows下libcurl 7.40预编译包实战:VS配置、避坑与并发请求

Windows下libcurl 7.40预编译包实战:VS配置、避坑与并发请求

简介:这份资源是 libcurl 7.40 在 Windows 平台下编译完成的成品库,面向需要在 C/C 项目中集成 HTTP 请求能力的开发者,尤其适合不想自行折腾编译、希望直接调用的初学者与中级工程师。压缩包共 17 个文件,以 9 个 h 头文件、6 个…

2026/10/16 7:18:05 阅读更多 →
材通PPR精工保温管|全国区域代理商招募中

材通PPR精工保温管|全国区域代理商招募中

很多人买热水管时容易踩一个认知坑:这水管“耐95℃”,放阳台、露台、屋顶肯定没问题。结果过一个夏天,明装那段管子表面发白、手一敲邦邦硬,这就是被紫外线“烤”老了。耐热的PPR管子为何扛不住晒?耐热和耐晒&#xff…

2026/10/16 7:17:05 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →