腾讯会议,AI 纪要和逐字稿质量都不错,怎么保存到本地? 本文给你一条能抄的命令和一句能抄的提示词,数据均来自真实执行。
一、先说痛点:看得见,拿不走
上周我进行了一次线上交流,腾讯会议自动生成了 AI 纪要和逐字稿。但我想存下来,发现三件事:
① 逐字稿没有导出按钮只能一屏一屏选中、复制。
② 滚动条能拉到底,但那是假的鼠标往下滚,滚到一半,上面的内容就"消失"了——DOM 被回收。
③ Ctrl+A全选只有十几条数据是 React 运行时渲染的,静态 HTML 里一个字都没有。
怎么办呢?毕竟会议链接访问地址过了有效期就不能访问了。
二、先别急着写代码:任务是怎么被"说清楚"的
虽然我是Playwright博主,但也不想自己从头写代码呀。我给了WorkBuddy提问:
结果还行,比我预期要快的就搞定了。
别急着划走,下面的内容可能更重要。
很多人用 AI 干活,第一句是"帮我写个爬虫下载会议录制",然后拿到一堆跑不通的代码。
问题不在 AI,在于任务没被定义清楚。
我这次给 AI 的提示词,是一份标准的任务委托书,四层信息:
① 目标把链接里的内容固化下来。 → 定义的是"做完"的标准,而不是"写段代码"。
② 首选路径你如果有浏览器自动化能力,就用 Playwright 干。 → 给出技术手段,缩小 AI 的搜索空间。
③ 降级路径(Plan B)⭐ 最值钱干不了就引导我手动下载。 → 给 AI 一个失败出口。
④ 输出约束文件名、保存目录写死。 → 产物可直接落地,不用二次整理。
为什么第 ③ 条最值钱?
没有 Plan B 的提示词,AI 遇到 403 会开始编造:假装下载成功、给你一堆"理论上可行"的代码。 有了 Plan B,AI 知道自己"可以承认干不了",反而会更诚实去试、去报错。
实测中还有个细节值得说: 我提示词里写的是"请模拟登录",但 AI 探测后发现根本不需要登录,就直接跳过了。
好的 AI 执行者会修正你提示词里的错误假设,而不是盲从。 如果你把"必须模拟登录"写死,它就会去研究扫码、Cookie 注入,白扔两小时。
三、拆解三段核心技术
翻看workbuddy实现过程,看看用到哪些Playwright技巧,以及值得我们学习的地方。
3.1 免登录:为什么 /crm/链接能直接打开
录制回放有两种链接形态:
/crm/—— 创建者分享的公开链接,带一次性访问令牌,无需登录
其他形态—— 需要企业/个人账号登录
有个坑:请求 /crm/后会 302 跳转到 /cw/,标题变成「录制文件」。 这个跳转是内部的,别被吓到,以为要登录了。
代码上必须用持久化上下文,不是普通 launch():
python ctx = p.chromium.launch_persistent_context(
user_data_dir="~/.wemeet-profile",
headless=False,
args=["--disable-blink-features=AutomationControlled"],
viewport={"width": 1440, "height": 900},
)
两个理由:页面下发的 am_tokenCookie 后面下载 MP4 全靠它; --disable-blink-features=AutomationControlled干掉 navigator.webdriver指纹。
3.2 虚拟滚动:为什么 innerText只给你 6%
这是最硬的一块。
长列表的经典优化:浏览器不把 500 条数据全挂到 DOM 上,而是——
只渲染可视区 + 上下缓冲区(约 1.5 屏)的节点 用一个占位高度撑出完整滚动条(所以你能拉到底,但那是假的) 滚动时复用同一批 DOM 节点,只改里面的文字
实测数据:
容器: .minutes-module-list
scrollHeight = 18,354 px ← 理论总高度(撑出来的,刚加载时只有 10,825)
clientHeight = 669 px ← 可视高度
可视文本 = 1,078 字符 ← 真实挂载在 DOM 上的量
scrollHeight和innerText之间的巨大差值,就是虚拟滚动的指纹。
破解思路:每次只有一屏是真的,那就滚一段、抓一段、拼起来; 相邻两段必然重叠,按最长「后缀-前缀」匹配去重。
两个关键参数:
滚动步长 = 0.6 屏小于一屏才不会跳过未渲染的部分;0.6 保证约 40% 重叠。
settle_ms= 700ms复用节点后重渲染要时间,太快会抓到上一屏残影。
⚠️ 这里我踩了个坑,值得单独讲
第一版我给重叠窗口设了个"看起来很合理"的上限:
python merge_chunks(chunks, max_overlap=2000) # ❌ 错了
结果:18,844 字符的稿子被拼成 50,328 字符——2.67 倍。
为什么?某些长段落(3,000+ 字符)的真实重叠超过了 2000, 窗口太小 → 匹配失败 → best = 0→ 整段原样追加。
这个坑的狠处在于:它不报错,只静默产出一份"看起来很完整"的废数据。
所以我加了一道质量门禁——时间戳单调性自检:
python ts = re.findall(r"(?m)^\d{1,2}:\d{2}$", transcript)
regress = sum(1for a, b inzip(ts, ts[1:]) if b < a)
真实输出对比:
# 错误版(max_overlap=2000)
[step 3] 逐字稿 50328 字符
[check] 时间戳 291 个,回退 13 处 ← 一眼看出重复了
# 正确版(不设上限)
[step 3] 逐字稿 18844 字符
[check] 时间戳 131 个,回退 0 处 -> 时序正常 ✅这就是测试思维在爬虫里的价值:给数据加一道断言,让错误自己跳出来。
3.3 网络拦截:403 的真相
拿到 MP4 直链后我以为稳了,结果连挂三次:
直接 urlopen(video.src) → ❌ HTTP 403
用 page.request.get() → ❌ HTTP 403(很多人以为它会带浏览器 Cookie,实测不会)
补 Referer 和 UA → ❌ HTTP 403403 的原因不是 token 过期,是缺请求头。
既然猜不出来,就让浏览器自己发一次请求,我拦下来照抄:
python defon_route(route, request):
if".mp4"in request.url:
captured["url"] = request.url
captured["headers"] = dict(request.headers) # 原样抄走
route.continue_()
page.route("**/*", on_route)
page.evaluate("() => document.querySelector('video').play()")
拦截到的两个关键头:
Range: bytes=0-媒体流的标准起始请求。缺了直接 403,正常应返回 206 Partial Content。
Cookie: am_token=...页面下发的访问令牌。缺了鉴权失败。
用这两个头回放请求:
[info] HTTP 206 | video/mp4 | 80.9 MB
已下载 20/81 MB (1s)
已下载 40/81 MB (3s)
已下载 60/81 MB (4s)
已下载 80/81 MB (5s)81 MB,5 秒。因为绕开了浏览器的解码/缓存层,直接走裸 HTTP 流。
四、合规边界(这一段请先看)
技术本身是中性的,用法不是。四条边界,别越线:
✅ 可以做固化你自己创建的会议;固化客户明确授权留档的会议。
❌ 不做破解验证码;绕过他人站点的访问控制;抓取未授权内容。
❌ 不外流会议号、链接、token、Cookie——任何可识别信息。
❌ 不进对外产物逐字稿正文属于敏感内容,不出现在任何对外交付物里。
一句话:这个工具只是把你本来就能看到的页面内容自动存下来, 不提供任何绕过权限控制的能力。请遵守平台服务条款。
五、建议收藏:判断口诀卡片
看到什么 → 该怎么干
滚动条很长,DOM 节点很少→ 虚拟滚动。分段滚(0.6 屏步长)+ 重叠拼接。
数据拿不到,但浏览器能显示→ 网络拦截。别猜接口,用 page.route让浏览器告诉你。
拼接完字符数明显偏大→ 先数时间戳。回退 > 0就是拼重复了,别交付。
下载媒体 403→ 缺 Range+ Cookie,不是 token 过期。
进阶:拦截到 XHR/Fetch 后往往能直接找到后端 JSON 接口—— 别再爬 DOM 了,直接请求接口,稳得多也快一个数量级。
六、写在最后
三个技术点:
① 免登录— /crm/分享链接自带令牌,持久化上下文保住 Cookie。 ② 虚拟滚动— 0.6 屏步长分段滚 → 最长重叠拼接 → 时间戳自检(救了我一次)。 ③ 网络拦截— 不猜请求头,用 page.route原样抄下来回放。
但最让我有收获的不是这三段代码,而是第二节那件事:
我把任务写成了「目标 + 首选路径 + 降级路径 + 输出约束」的委托书。 AI 在里面自己修正了我"必须模拟登录"的错误假设,自己发现了虚拟滚动,自己加了数据自检。
会写提示词的人和不会写的人,用的是同一个 AI,拿到的却是两种结果。前者拿到能跑的产物,后者拿到一堆看起来很专业的代码片段。
建议收藏。下次遇到"看得见拿不走"的页面,直接翻这张口诀卡。
评论区聊聊:你手上最想固化的一场会议,卡在哪一步?是滚动抓不全,还是视频 403?说出来,我逐条回。
📦 源码包:wemeet_recorder.py(单文件工具)+ requirements.txt+ README.md+ run_guide.md+ FAQ.md+ 真实运行日志(含失败版对照)+ SKILL.md(可封装成 Agent 技能)+ 零依赖 demo,按包内 run_guide 五步即可复现。
后台回复「会议固化」,获取完整配套源码包。