接口与UI自动化测试框架模板:测开提效实战指南

做测开这几年,我最大的感受就是:真正耗时间的不是业务测试逻辑本身,而是每接一个新项目,都要从零搭一遍自动化框架。目录结构重新建、公共方法重新写、日志和报告重新配,甚至连“怎么读取配置”这种几十行代码都要再敲一遍。这种重复劳动,干一次是学习,干十次就是纯纯的内耗。

所以我花了不少精力,把日常工作里最高频的两套自动化场景沉淀成了通用模板:一套是面向接口自动化的 pytest + requests 框架,另一套是面向 UI 自动化的 pytest + Selenium/Playwright 框架。两套模板的核心思路都一样:分层清晰、开箱即用、替换业务代码就能跑。这篇文章就把这两套模板的结构、关键实现和落地细节完整拆开,希望能给正在搭框架或准备重构的测开同学一些参考。

1. 为什么测开需要两套通用模板

1.1 重复造轮子的代价,比想象中更大

很多团队的第一套自动化脚本都是“小作坊”模式:一个脚本文件从头写到尾,公共函数塞在 utils 里,测试数据写在代码里。这种写法在用例只有十几条的时候还挺爽,因为改起来直接,跑起来也快。但用例一旦超过 50 条,或者需求迭代进入第二个月,问题就全出来了。用例之间开始互相依赖,某个接口的响应被另一个用例硬编码引用,前端元素定位散落在各个脚本里,一旦页面改版,排查都要排查半天。

我见过比较夸张的一个项目,自动化用例 80% 都是拷贝粘贴改出来的,公共方法有五个版本,谁也不敢动。后来实在跑不下去了,只能花两个迭代重构。与其这样,不如在最开始就准备一套通用模板,把目录结构、公共方法、数据驱动机制、报告输出全部固定下来,业务代码只是往里面填。

1.2 两套模板的适用边界和选型逻辑

为什么偏偏是这两套,而不是“一套模板走天下”?因为测试金字塔的规律摆在那里:接口自动化成本低、稳定性高、执行快,适合覆盖业务逻辑和异常链路;UI 自动化贴近用户真实操作,适合覆盖关键主流程和端到端验证,但成本高、容易受环境波动影响。两者互补,但不能互相替代。

我的建议是:

  • 如果被测对象有明确接口,优先用接口自动化模板覆盖绝大部分回归场景;
  • 如果涉及多系统串联、前端交互验证、或者需要模拟真实用户操作,再引入 UI 自动化模板;
  • 如果业务还在快速迭代、页面结构一天一变,UI 自动化可以先只做主流程,别急着全覆盖。

这个选型逻辑说白了就是 ROI。同样写一条用例,接口用例可能十几分钟搞定,UI 用例可能要半天,还得持续维护。用模板不是为了炫技,而是为了把固定成本降下来,让自动化在项目里能真正活下去。

2. 第一套模板:接口自动化通用框架

2.1 目录结构:一眼就能看懂的分层

接口自动化模板我建议按照“数据驱动 + 分层”的思路来组织,目录结构大概是这样的:

api_test_template/ ├── config/ │ ├── __init__.py │ ├── settings.py # 全局配置、环境切换 │ └── dev.yaml # 开发环境配置 ├── core/ │ ├── __init__.py │ ├── http_client.py # requests 会话封装 │ ├── assert_utils.py # 断言工具 │ ├── logger.py # 日志封装 │ └── read_data.py # yaml/excel/json 读取 ├── data/ │ ├── login_data.yaml # 登录接口测试数据 │ └── order_data.yaml # 订单接口测试数据 ├── testcases/ │ ├── __init__.py │ ├── conftest.py # fixture 和钩子 │ ├── test_login.py │ └── test_order.py ├── reports/ │ └── ... # 测试报告输出目录 ├── requirements.txt ├── pytest.ini └── run.py # 统一入口脚本

这套分层的逻辑很简单:config 管环境,core 管能力,data 管数据,testcases 管业务。测试用例里基本看不到 requests 的细节,也不会有环境地址写死的情况,看到的都是业务描述和数据引用。优势很明显:新人进来不用看全部代码,只需要知道“我要测什么接口,应该往 data 里加数据、往 testcases 里加用例”。

2.2 核心模块的实现与理由

先说 http_client.py,这是所有接口调用的底座。我封装它的原因有三个:统一处理基础请求头、统一异常捕获、统一日志记录。如果没有这一层,每个用例里直接调 requests.post,且不说代码重复,出了问题连最基本的请求耗时、返回状态码都没人记。

# core/http_client.py import requests import time from core.logger import get_logger logger = get_logger(__name__) class HttpClient: def __init__(self, base_url, timeout=10): self.session = requests.Session() self.base_url = base_url self.timeout = timeout self.session.headers.update({ "Content-Type": "application/json;charset=UTF-8" }) def request(self, method, path, **kwargs): url = self.base_url + path kwargs.setdefault("timeout", self.timeout) start_ts = time.time() try: resp = self.session.request(method, url, **kwargs) logger.info(f"请求 {method} {url} 状态码={resp.status_code} 耗时={time.time() - start_ts:.3f}s") return resp except requests.RequestException as exc: logger.error(f"请求异常 {method} {url}: {exc}") raise def get(self, path, **kwargs): return self.request("GET", path, **kwargs) def post(self, path, **kwargs): return self.request("POST", path, **kwargs)

注意这里我用的是 requests.Session 而不是裸调 requests.get/post。Session 会自动管理连接池,在跑大量用例的时候能复用底层 TCP 连接,实测同一套用例用 Session 比裸请求整体能快 20% 到 30%,这个提升在回放 200 条用例时体感非常明显。

conftest.py 是 pytest 的灵魂。我在里面定义了一个全局的 client fixture,以及一个自动读取 yaml 测试数据的钩子:

# testcases/conftest.py import pytest import yaml from core.http_client import HttpClient from config.settings import BASE_URL @pytest.fixture(scope="session") def client(): http_client = HttpClient(BASE_URL) yield http_client http_client.session.close() def load_test_data(file_name): with open(f"data/{file_name}", encoding="utf-8") as f: return yaml.safe_load(f) @pytest.fixture() def login_data(): return load_test_data("login_data.yaml")

用 yaml 做数据驱动是我比较坚持的做法。对比 Excel 和 JSON,yaml 的书写成本低,支持注释,层级关系清晰,而且天然就是 Python 字典的结构。Excel 适合非技术人员维护大量数据,JSON 写起来括号多容易错,yaml 在这三者里是对测开同学最友好的一种。

2.3 数据驱动和多环境切换的提效点

数据驱动的核心不是“把数据放到 yaml 里”这个动作,而是“用例逻辑与测试数据分离”这种思维。举一个例子:登录接口需要验证正常登录、密码错误、账号不存在、账号锁定等多种场景。如果不用数据驱动,每条用例都是一段几乎一样的代码。用数据驱动之后,用例部分可以收敛成一条:

# testcases/test_login.py import pytest class TestLogin: @pytest.mark.parametrize("case", [ {"desc": "正常登录", "payload": {"username": "admin", "password": "123456"}, "code": 0}, {"desc": "密码错误", "payload": {"username": "admin", "password": "wrong"}, "code": 1001}, {"desc": "账号不存在", "payload": {"username": "nobody", "password": "123456"}, "code": 1002}, ]) def test_login(self, client, case): resp = client.post("/api/login", json=case["payload"]) assert resp.json()["code"] == case["code"]

这样写有一个明显的好处:以后新增场景只需要往列表里加一个字典,不用新增方法,也不会影响已有用例。而且用例名称、描述、预期结果全部一目了然,测试报告读起来就是业务语言,而不是一堆看不懂的 response body。

多环境切换我放在了 settings.py 里解决。做法很简单:读取环境变量中的 RUN_ENV,默认走 dev,通过环境变量切到 staging 或 prod 配置,而不是每次改代码。我之前见过有人在代码里直接改 BASE_URL,然后不小心把带数据的测试环境给刷了,这种事故就是配置管理不规范导致的。用模板之后就再没出现过这种问题。

3. 第二套模板:UI 自动化与端到端用例框架

3.1 UI 自动化为什么更需要模板

UI 自动化比接口自动化更容易失控,原因是它天然依赖环境:浏览器版本、驱动程序、页面加载速度、网络波动、弹窗遮挡,任何一个环节抖动,用例就可能挂。如果没有一套统一模板,每个用例自己处理等待、自己截图、自己拼元素定位,那最终结果就是“今天能跑,明天不能跑,没人知道为什么”。

所以 UI 自动化模板的第一个目标不是写更多用例,而是建立稳定性机制。第二个目标才是复用。页面对象(Page Object Model,简称 POM)模式就是为此设计的:把页面元素定位和操作方法封装成类,测试用例只描述业务动作,不碰 CSS 选择器或 XPath。

3.2 POM 模式与公共操作封装

我在模板里用的是 pytest + Selenium,同时对关键公共操作进行了二次封装。为什么不用原生 find_element?因为原生方法在元素不存在时直接抛异常,不会等待,也不会留下现场信息,对于排查问题来说很不友好。封装后的方法长这样:

# core/page_base.py import time from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class PageBase: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def click(self, locator): elem = self.wait.until(EC.element_to_be_clickable(locator)) elem.click() def fill(self, locator, text): elem = self.wait.until(EC.visibility_of_element_located(locator)) elem.clear() elem.send_keys(text) def get_text(self, locator): elem = self.wait.until(EC.visibility_of_element_located(locator)) return elem.text def screenshot(self, name): self.driver.save_screenshot(f"reports/screenshots/{name}_{int(time.time())}.png")

这里的关键点是“显式等待”,而不是 time.sleep 这种固定等待。显式等待是条件满足就继续,不满足就等到超时;固定等待不管页面状态如何,都要傻等几秒,既慢又不稳定。实测下来,同样一版用例,把 sleep 全部换成显式等待之后,执行时间能缩短三分之一左右,稳定性还有明显提升。

页面对象类则对应业务页面,比如登录页、订单页:

# pages/login_page.py from selenium.webdriver.common.by import By from core.page_base import PageBase class LoginPage(PageBase): username_input = (By.CSS_SELECTOR, "#username") password_input = (By.CSS_SELECTOR, "#password") login_button = (By.CSS_SELECTOR, "button[type='submit']") def login(self, username, password): self.fill(self.username_input, username) self.fill(self.password_input, password) self.click(self.login_button)

这样设计之后,用例层就变得非常薄:

# testcases/test_login_page.py from pages.login_page import LoginPage class TestLoginPage: def test_user_login(self, driver): page = LoginPage(driver) page.open("/login") page.login("admin", "123456") assert page.get_current_url().endswith("/home")

页面元素一旦变化,只需要改页面对应类里的一行定位,而不是满项目找在哪里用到了这个输入框。这就是 POM 的最大价值:把变化的范围限制在一个地方。

3.3 稳定性治理:等待、截图、重试、失败处理

UI 自动化最怕“偶现失败”。同一段用例,跑三遍挂一遍,还复现不了。我的经验是:遇到偶现失败,不要急着改业务逻辑,先看失败时的截图和录屏,八成是页面加载慢或者元素被弹出框遮挡。

模板里内置了几个稳定性组件:

第一个是失败自动截图。我在 pytest 的 hook 里加了失败处理,用例失败时自动保存截图并附加到 HTML 报告,这样一眼就能看出是定位错了还是页面崩了。

第二个是失败重试机制。用了 pytest-rerunfailures 插件,对已知的不稳定用例设置 reruns=2,只对 UI 层用例开,接口层不建议开,因为接口层失败往往是真实逻辑问题,重试反而掩盖 bug。

第三个是 headless 模式。CI 环境没有界面,运行到浏览器时如果没配置 headless,直接报错。模板里用一个配置开关控制,本地调试时开界面模式,CI 里切 headless。

关于 Selenium 和 Playwright 怎么选,我个人的倾向是:如果团队已经熟悉 Selenium,生态成熟,没必要迁移;如果是新团队从零开始,直接上 Playwright 会更省事。Playwright 自带浏览器驱动管理、自动等待、录制、多标签页处理都更顺手。但这不代表 Selenium 过时了,很多老项目和开源生态都还在用 Selenium,关键是模板机制本身是通用的,底层引擎可以替换。

4. 配套的日常提效工具箱

4.1 日志和报告:不能只在本地跑通就没后续

自动化框架跑完出一份报告,这算是基本要求,但很多模板会忽略日志的“可检索性”。我见过一些项目的 log 文件不分级别、不分时间,全塞在一个文件里,出了问题 Ctrl+F 找关键词找半天。模板里我用 logging 模块按天生成日志,并且把请求状态、响应摘要、耗时都打进去。这样即使测试报告没细看,也能通过日志快速定位到具体是哪个请求导致的失败。

报告这块,接口层我用 pytest-html 加自定义摘要,UI 层用 pytest-html 附带截图展示。没有上太重型的测试平台,因为对多数项目来说,一个静态 HTML 报告加上错误日志,足够日常回归使用了。真要上平台,模板的用例结构也可以无缝对接,因为数据驱动和分层设计与 Allure 这类工具天然兼容。

4.2 一条命令完成环境初始化

模板要做到“拿来就能跑”,环境初始化就不能靠手点。我在根目录放了一个 setup 脚本,做的事情包括:创建虚拟环境、安装依赖、检查浏览器驱动、初始化报告目录。首次使用只需要执行:

python setup.py pytest -v

这里有一个细节:依赖版本不要全部放开,最好锁定大版本,尤其像 requests、pytest 这些核心包。我在 requirements.txt 里写的是:

pytest>=7.0,<8.0 requests>=2.28,<3.0 PyYAML>=6.0,<7.0 pytest-html>=3.2,<4.0

锁定大版本是为了避免自动化跑着跑着,因为某个库发布了不兼容的新版,整个框架突然崩掉。测开框架的第一要务是可控,不是追新。

4.3 从模板到业务的 5 步落地流程

模板本身不是最终交付物,业务用例才是。我复制模板到新项目时,通常会走一套固定的流程:

  1. 复制模板目录,改项目名和包名;
  2. 在 config 里新增被测环境的 base_url、账号、密钥等基础配置;
  3. 根据接口文档或页面清单,在 data 目录或 pages 目录下补业务数据/页面对象;
  4. 写第一批核心用例,跑通一条完整链路;
  5. 提交代码,配置定时任务或 CI 触发。

这五步走下来,一个项目的第一版自动化框架通常半天就能跑起来,剩下的时间全部投入业务用例编写。这才是模板真正“提效”的地方:它把最没价值的搭架子环节压缩到最小。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

下面这张表是我在实际推广模板过程中被问得最多的问题,连同排查思路一起列出来:

现象可能原因排查方法与处理
接口用例能跑到一半突然超时接口依赖的第三方服务不稳定查看日志里超时接口的耗时,确认是网络问题还是服务问题,对非核心依赖加 try 或延迟重试
切换环境后大量用例失败配置没切换干净或测试数据污染检查所有 base_url 引用是否都走了配置,确认环境数据是否被上一次测试写脏
UI 用例偶发找不到元素元素是异步加载的把固定 sleep 替换为显式等待,确认元素是否在 iframe/Shadow DOM 中
浏览器启动后 driver 报版本不匹配浏览器自动升级,driver 版本落后模板支持自动下载匹配驱动,或固定浏览器版本
报告里截图看不到报告目录被清理或路径含中文字符统一用绝对路径拼接报告目录,避免相对路径在不同目录下跑乱套
数据驱动用例太多,单条定位困难用例 ID 不清晰给每条用例增加业务化 name,测试报告中用 label 标注模块和场景

5.2 几个值得长期坚持的避坑习惯

第一个习惯是“用例之间永远不要有执行顺序依赖”。我见过不少团队的用例是 A 登录、B 下单、C 支付,C 依赖 B 的订单号,B 依赖 A 的 token,一旦单独跑 C 就挂。这种用例集连基本的独立性都没有,根本算不上自动化回归。正确做法是每个用例自己完成前置数据准备,要么通过接口造数,要么在用例内部调用公共方法创建依赖对象。

第二个习惯是“不要试图让 UI 用例覆盖所有异常场景”。异常分支和边界值优先用接口自动化覆盖,UI 层只保留用户最典型的高频操作路径。这样既能控制执行时间,也能减少维护成本。我见过团队一门心思把 UI 用例数量做到上千条,结果每天光是修失败用例就忙到下班,这就本末倒置了。

第三个习惯是“模板要持续迭代,不能一沉不变”。比如之前我的接口模板用 requests,后来团队引入 gRPC,我就把 core 层扩展了一下,新增了一个 grpc_client。模板是活的东西,随着团队技术栈变化要持续维护,否则它的价值会随着时间慢慢衰减。

6. 一点个人体会

如果只挑一条经验分享给刚接触自动化的测开同学,我可能会说:先搭框架,再谈用例数量。框架决定了你的自动化能稳定跑多久,用例数量决定了你的自动化能覆盖多少业务。没有框架的用例是负债,有了框架的用例才是资产。

这两套模板花了我不少业余时间打磨,但带来的回报也确实可观。现在不管接手什么新项目,我基本不用考虑“自动化架子怎么搭”这个问题,直接套模板,把精力集中在理解业务、设计用例上。这可能就是“提效”的本质——不是让你在同一件事上做得更快,而是让你把时间分配到更有价值的事情上去。

后续如果有空,我可能会把两套模板整合到一个 CLI 工具里,做成“一条命令生成指定类型的自动化项目”,再结合任务调度做自动化巡检。等玩出效果了,再回来继续分享。

相关新闻

Vue前端用pdf-lib实现PDF盖章签名下载:坐标系避坑与完整指南

Vue前端用pdf-lib实现PDF盖章签名下载:坐标系避坑与完整指南

简介&#xff1a;这是一份基于Vue.js实现PDF上传、盖章与签名功能的完整项目源码包&#xff0c;面向需要为合同、审批等文档流程引入在线签章能力的开发者&#xff0c;适合具备一定Vue基础、希望快速落地的前端学习者。压缩包共19个文件&#xff0c;含5个Vue组件、5个JavaScrip…

2026/10/20 10:04:46 阅读更多 →
STM32F4固件库架构解析:从工程搭建到串口调试与HAL迁移避坑指南

STM32F4固件库架构解析:从工程搭建到串口调试与HAL迁移避坑指南

简介&#xff1a;STM32F4固件库是意法半导体为STM32F4系列微控制器提供的软件开发框架&#xff0c;面向嵌入式工程师与学生开发者&#xff0c;可简化基于ARM Cortex-M4内核的应用开发。压缩包共2425个文件&#xff0c;大小47.1MB&#xff0c;以html说明文档、c/h源代码、png图片…

2026/10/20 10:04:46 阅读更多 →
AI驱动自动化测试工具实测:如何用自然语言替代XPath,解决UI选择器维护难题

AI驱动自动化测试工具实测:如何用自然语言替代XPath,解决UI选择器维护难题

中午在技术群里刷到一条消息&#xff1a;某科技巨头开源了一个主打AI驱动的自动化测试工具。消息一出&#xff0c;群里的反应几乎和我预想的一样&#xff0c;先是“卧槽&#xff0c;又一个颠覆级项目”&#xff0c;再是“以后写UI自动化是不是不用维护选择器了”&#xff0c;最…

2026/10/20 10:04:46 阅读更多 →

最新新闻

VS2019快速集成wxWidgets二进制包实战指南

VS2019快速集成wxWidgets二进制包实战指南

1. 项目概述&#xff1a;为什么“直接使用二进制文件”是wxWidgets开发中最常被卡住的第一关 在Visual Studio 2019环境下配置wxWidgets&#xff0c;绝大多数人踩进的第一个坑&#xff0c;不是代码写错&#xff0c;也不是逻辑出问题&#xff0c;而是——连编译都过不去。你下载…

2026/10/20 11:33:30 阅读更多 →
AI芯片设计黑盒困局:从不可解释到可控黑盒的工程实践

AI芯片设计黑盒困局:从不可解释到可控黑盒的工程实践

“AI 在芯片领域依然是个黑盒。”这句话不是我从某篇报告里抄来的&#xff0c;是我在上一个流片项目的复盘会上&#xff0c;被自己的算法同事一句一句追问出来的。当时我们上线了一个辅助布局优化的AI模型&#xff0c;指标提升很漂亮&#xff0c;可一旦被问到“为什么这几百个标…

2026/10/20 11:33:30 阅读更多 →
HTC Vive OpenVR 配置避坑指南:SDK 1.25.4 + SteamVR 1.26.4 黄金组合

HTC Vive OpenVR 配置避坑指南:SDK 1.25.4 + SteamVR 1.26.4 黄金组合

简介&#xff1a;本资源是面向VR开发初学者与进阶者的OpenVR实战入门项目&#xff0c;聚焦HTC Vive设备的API调用与Tracker扩展应用&#xff0c;解决开发者在跨平台VR交互开发中接口适配难、追踪数据解析复杂等实际问题。压缩包共9个文件&#xff0c;含4个核心Python脚本&#…

2026/10/20 11:33:30 阅读更多 →
Llama 3 精读:FP8 量化与长上下文实测经验分享

Llama 3 精读:FP8 量化与长上下文实测经验分享

1. 为什么值得花时间精读 Llama 3Llama 3 发布之后&#xff0c;我身边不少做推理部署和模型微调的朋友都在第一时间拉取了权重做实测。大家最关心的其实不是榜单上的分数&#xff0c;而是两个非常实际的问题&#xff1a;第一&#xff0c;这个模型在FP8 量化之后精度到底掉多少&…

2026/10/20 11:33:30 阅读更多 →
腾讯广告回收业务推广类目梳理:可投品类、禁投品类及资质要点

腾讯广告回收业务推广类目梳理:可投品类、禁投品类及资质要点

前言很多再生资源、回收行业的从业者&#xff0c;会选择腾讯广告&#xff08;朋友圈、视频号、腾讯新闻等流量位&#xff09;来收集 B 端企业或 C 端散户的业务咨询信息。但回收类目细分多、监管差异大&#xff0c;不少商家开户后遇到广告拒审、计划下架、账户限流等问题。多数…

2026/10/20 11:33:30 阅读更多 →
专科生论文降AI率实战指南:九款降AIGC工具测评与避坑要点

专科生论文降AI率实战指南:九款降AIGC工具测评与避坑要点

最近后台问得最多的不是论文怎么写&#xff0c;而是“论文写完了AI率太高怎么办”。很多专科生现在交课程论文、毕业设计、实习报告之前&#xff0c;都要先跑一遍AIGC检测&#xff0c;结果一出来就慌了&#xff1a;明明是自己查阅资料写的初稿&#xff0c;只是用AI帮忙润了润色…

2026/10/20 11:32:30 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →