Setup & Installation
Install Fetch Archive to Lexiang using the ClawHub CLI or OpenClaw CLI:
clawhub install fetch-archive-to-lexiangIf the CLI is not installed:
npx clawhub@latest install fetch-archive-to-lexiangOr install with OpenClaw CLI:
openclaw skills install fetch-archive-to-lexiangWhat This Skill Does
Fetch Archive to Lexiang is a Creative & Media skill for OpenClaw by ajaxhe.
抓取链接内容 & 转存知识库
概述
将文章 URL(免费/付费/登录墙)抓取为结构化 Markdown,并自动转存到乐享知识库,实现素材归档和可追溯。
最终产出物
<项目子目录>/<原文标题>.md— 完整文章 Markdown(含图片引用)<项目子目录>/<原文标题>_meta.json— 结构化元信息(原文链接、作者、发布时间、抓取时间等)<项目子目录>/images/— 所有文章配图- 乐享知识库中的文档副本(按天维度归档)
文件命名规则(重要)
- 必须使用原文标题命名,不要用
article.md等通用名称 - 文件名格式:
<原文标题>.md、<原文标题>_meta.json - 示例:
How Notion uses Custom Agents.md、How Notion uses Custom Agents_meta.json - 如果标题中包含文件名不合法字符(
/、\、:等),替换为- - 乐享知识库转存时也使用原文标题作为文档标题
工作流程
Step 1:素材收集
抓取方式决策树
根据 URL 类型选择抓取方式(按优先级排列):
- 微信公众号文章(
mp.weixin.qq.com)→ 必须用fetch_article.py(web_fetch无法获取图片) - YouTube 视频 → 使用
yt_download_transcribe.py(yt-dlp 下载 + Whisper 转录 + AI 翻译),详见下方「YouTube 视频处理」章节 - 播客音频(小宇宙
xiaoyuzhoufm.com、Apple Podcasts 等)→ yt-dlp 下载音频 + Whisper 转录,详见下方「播客音频处理」章节 - 付费/登录墙文章 → 用
fetch_article.py(Cookie 注入或 CDP 模式) - 免费图文文章(正文含图片/截图/图表)→ 必须用
fetch_article.py(web_fetch只能返回文本,无法提取和下载页面中的图片) - 免费纯文字文章(正文无配图)→ 可用
web_fetch,内容不完整时切换fetch_article.py - 文字观点 → 直接整理
- 图片素材 → 分析图片内容
⚠️ 关键原则:
web_fetch工具只能返回文本内容,无法提取和下载页面中的图片。任何包含图片、截图、图表的文章,都必须使用fetch_article.py抓取,否则图片信息会完全丢失。当不确定文章是否含图时,默认用fetch_article.py。
付费/登录墙文章获取
适用于所有需要登录态才能查看全文的网站(Substack 付费订阅、Medium 会员、知识星球、财新网、The Information 等),使用 fetch_article.py 脚本:
# Cookie 注入模式(默认,适用于大部分站点)
python scripts/fetch_article.py fetch <URL> --output-dir <项目子目录>
# CDP 模式(适用于 Cloudflare 保护站点、需要 Google 账号登录的站点)
python scripts/fetch_article.py fetch <URL> --output-dir <项目子目录> --cdp
两种浏览器模式:
| 模式 | 参数 | 原理 | 适用场景 |
|---|---|---|---|
| Cookie 注入 | (默认) | 从 Chrome Cookie DB 提取 cookies → 注入 Playwright 浏览器 | Substack、Medium 等大部分站点 |
| CDP | --cdp |
通过 Chrome DevTools Protocol 连接用户真实 Chrome(port 9222),复用完整登录态 | OpenAI、Cloudflare 保护站点、LinkedIn、Google 系网站等会检测自动化浏览器或有反爬的站点 |
何时必须用 CDP 模式:
- Cloudflare 保护站点(如 openai.com):Cloudflare 的 JS challenge 会阻拦 Playwright 自动化浏览器。CDP 模式连接用户真实 Chrome 可以绕过。脚本会自动检测 Cloudflare challenge 页面("Just a moment..." 等)并等待验证通过。
- Google 登录页面(如 LinkedIn "通过 Google 登录"):Google 登录页面会检测 Playwright 并拒绝登录。CDP 模式完全绕过此检测。
自动升级:对于已知的 Cloudflare 站点(
openai.com等),即使未指定--cdp,脚本也会自动切换到 CDP 模式。
CDP 模式前置条件:确保 Chrome 浏览器已开启 CDP 远程调试端口:
# 启动 Chrome(开启 CDP 远程调试端口 9222)
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 &
# 验证 CDP 端口可连接
curl -s http://localhost:9222/json/version
如果 Chrome 已在运行但未开启 CDP,脚本会尝试优雅关闭 Chrome 后以 CDP 模式重启。
工作原理:
- 自动从 Chrome 浏览器的 Cookie 数据库提取目标域名的登录 cookies
- 将 cookies 注入 Playwright 浏览器上下文
- 加载页面,自动检测并等待 Cloudflare challenge 通过(如有)
- 滚动加载懒加载内容、下载所有图片
- 自动格式转换:检测下载图片的真实格式(WebP/SVG 伪装成 .png/.jpg 很常见),自动转为真正的 PNG 以确保 PDF 生成和文档嵌入兼容
- 将正文转换为 Markdown(
article.md),图片保存到images/子目录 - 内容提取时自动选择最长的内容容器(避免只抓到免费预览区域)
标题提取增强(多策略回退):
- CSS 选择器优先级:
h1.post-title>article h1>[class*="title"] h1>h1 - 回退到
<meta property="og:title">→<meta name="title">→document.title - 自动清理标题中的网站后缀(如
" - Cursor"、" | Substack") - 正文中与已提取标题相同的第一个
<h1>会被自动去重,避免 MD 中标题重复
作者提取增强:
- CSS 选择器 +
meta[name="author"]+[rel="author"]+meta[property="article:author"]多策略回退
微信公众号文章(mp.weixin.qq.com)专项优化: 脚本对微信公众号文章有专门的检测和处理策略:
- 自动检测:识别
mp.weixin.qq.com域名,自动启用微信模式 - 无需登录:微信公众号文章是公开可读的,跳过登录检测和 Cookie 注入流程
- 专用内容选择器:使用
#js_content/.rich_media_content精准定位正文区域(而非通用选择器可能匹配到页面其他内容) - 标题提取:
#activity-name>h1.rich_media_title> 通用 h1 > meta 标签回退 - 作者提取:
#js_name(公众号名称)>.rich_media_meta_nickname> 通用选择器回退 - 日期提取:
#publish_time> 通用 time/date 选择器回退 - 图片懒加载增强:
- 微信图片使用
data-src+ IntersectionObserver 懒加载 - 滚动速度放慢(300px 步长、200ms 间隔)以确保触发所有 IntersectionObserver
- 强制将未触发的
data-src复制到src(兜底策略) - 图片下载时优先使用
data-src的高清原图 URL
- 微信图片使用
- 图片格式识别:微信图片 URL 格式特殊(
mmbiz.qpic.cn/...?wx_fmt=png),从wx_fmt查询参数推断文件扩展名 - Referer 防盗链:通过 Playwright 页面上下文的
page.request.get()下载图片,自动携带正确的 Referer 头
Substack 站点(如 www.lennysnewsletter.com)专项优化:
脚本对 Substack 托管的站点(*.substack.com、lennysnewsletter.com 等)有专门的登录检测和登录态缓存机制:
- 登录态缓存:登录成功后自动保存 Playwright
storage_state到~/.substack/storage_state.json,后续抓取直接复用,无需重复登录和邮箱验证 - 优先级:缓存
storage_state> Chrome cookies > 引导登录 - 自动检测登录状态:加载页面后检查右上角是否有用户头像(已登录)还是 "Sign in" 按钮(未登录)
- 已登录 → 直接抓取全文,并刷新缓存延长有效期
- 缓存过期 → 自动清理旧缓存,进入引导登录流程
- 未登录 → 打开可见浏览器窗口引导登录,用户在终端输入
y确认后二次验证,通过后自动缓存
独立登录命令(推荐首次使用时先执行):
python scripts/fetch_article.py login
此命令单独完成 Substack 登录并缓存,不需要指定文章 URL。后续所有 Substack 文章抓取都会自动复用此登录态。
非 Substack 站点的登录确认机制:
- 无 Chrome cookies 时自动切换到非无头模式,打开可见浏览器窗口
- 终端提示用户完成登录操作后按回车键继续
- 收到确认信号后重新加载页面并检测付费墙状态
付费墙检测:脚本同时检测以下信号:
- DOM 元素:
[data-testid="paywall"]、.paywall - 文本关键词:
This post is for paid subscribers、Subscribe to read、Upgrade to paid等 - 注意:不同网站的付费墙 DOM 结构和关键词不同,如遇新网站抓取不完整,需检查页面实际的付费墙标识并更新检测逻辑
判断内容是否完整的方法:
- 先用
web_fetch尝试获取,如果明显被截断(内容不完整、出现付费提示),则切换到fetch_article.py - 抓取完成后必须告知用户查看
article.md确认内容完整性 - 关注文章末尾是否有作者署名/总结段落作为完整性标志
- 如果用户反馈内容不完整,检查:(1) 登录账号是否有付费权限 (2) 页面是否有懒加载内容未触发 (3) 内容选择器是否匹配到了免费预览区而非全文区
产出物:
<项目子目录>/<原文标题>.md— 完整文章 Markdown(含图片引用)<项目子目录>/<原文标题>_meta.json— 结构化元信息(原文链接、作者、发布时间、抓取时间等)<项目子目录>/images/— 所有文章配图
<原文标题>_meta.json 格式:
{
"url": "原文链接",
"title": "文章标题",
"subtitle": "副标题",
"author": "作者",
"date": "发布时间",
"content_length": 12345,
"image_count": 5,
"images": ["images/img_01_xxx.png", ...],
"fetched_at": "2026-02-25T10:30:00"
}
X.com / Twitter 帖子抓取(必须用 CDP 模式)
X.com 是登录墙网站的典型代表,web_fetch 和普通 Cookie 注入模式都无法抓取,必须使用 CDP 模式:
# CDP 模式(必须)
python scripts/fetch_article.py fetch "https://x.com/<username>/status/<id>" --output-dir <项目子目录> --cdp
CDP 模式工作原理:
- 通过 Chrome DevTools Protocol (port 9222) 连接用户真实 Chrome 浏览器
- 复用浏览器中已登录的 X 账号会话
- 绕过自动化浏览器检测(X 会检测并阻止 Playwright/Selenium)
CDP 模式前置条件:
# 启动 Chrome 并开启 CDP 端口
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 &
# 验证
curl -s http://localhost:9222/json/version
X.com 抓取的特殊处理:
- 帖子内容会转换为 Markdown 格式
- 图片(帖子中的媒体)会下载到
images/目录 - 帖子中的链接会转换为 Markdown 链接格式
- 转发数、点赞数等元信息会保留
产出物:
<项目子目录>/<原文标题>.md— 帖子 Markdown<项目子目录>/<原文标题>_meta.json— 元信息<项目子目录>/images/— 帖子中的媒体图片
英文文章翻译为中英对照
对于英文文章(如 X 帖子、英文博客等),可以使用 OpenAI API 翻译为中英对照格式:
翻译脚本 (scripts/translate_article.py):
python scripts/translate_article.py <原文.md> <输出.md> --model gpt-4o-mini
翻译格式:
## 英文标题
[英文原文段落]
[中文翻译]
## 第二节英文标题
[英文原文...]
[中文翻译...]
翻译工作流:
- 先用
fetch_article.py抓取原文 - 用
translate_article.py翻译为中英对照 - 将翻译后的 Markdown 上传到乐享知识库
依赖:
OPENAI_API_KEY环境变量
使用 web_fetch 获取的免费文章
对于通过 web_fetch 获取到完整内容的免费文章,同样需要保存原文:
- 保存原文全文:将
web_fetch返回的内容直接保存为 Markdown,不做总结、不做摘要、不做改写,保持原文的完整结构和措辞 - 文件名使用原文标题:
<项目子目录>/<原文标题>.md - 手动构建
<原文标题>_meta.json,包含 URL、标题、作者、日期等元信息 - 如果文章包含图片,尽量下载保存到
<项目子目录>/images/
关键区分:
web_fetch工具可能会返回总结/摘要版本而非原文全文。如果返回的内容明显是总结(缺少原始段落、引用、细节),需要在web_fetch调用时明确要求"返回完整原始全文内容,不要总结或缩写"。保存到本地的必须是原文全文,而不是经过 AI 总结的摘要。
YouTube 视频处理(yt-dlp + Whisper + 翻译 + 乐享)
当用户提供 YouTube 视频链接时,使用 yt_download_transcribe.py 脚本完成完整的下载-转录-翻译-归档工作流。
⚠️ 重要:不要使用 web_fetch(无法获取视频内容),不要使用 NotebookLM(已替换为本地 Whisper 方案,速度更快、无外部依赖)。
工作流概述:
- yt-dlp 下载视频 → 本地
.mp4文件 - ffmpeg 提取音频 → WAV 格式(16kHz 单声道)
- Whisper 转录 → 带时间戳的文字稿
- AI 翻译(如果是英文)→ 中英对照格式的 Markdown
- 上传乐享知识库:
- 文字稿:以在线文档(page)格式上传,支持后续按块维度编辑更新
- 视频文件:以文件(file)格式上传
- 清理:上传成功后删除本地视频文件
Step 1:下载 + 转录 + 翻译
cd <项目子目录>
# 完整流程(下载 + 转录 + 翻译)
python3 scripts/yt_download_transcribe.py "<YouTube URL>" \
--output-dir . \
--whisper-model base
# 常用参数:
# --whisper-model tiny|base|small|medium|large 转录模型(越大越准但越慢)
# --skip-download 跳过下载(用于重新转录已下载的视频)
# --skip-translate 跳过翻译步骤
# --keep-audio 保留提取的音频文件
产出物:
<视频标题>.mp4— 下载的视频文件<视频标题>.md— 文字稿 Markdown(英文视频为中英对照格式)<视频标题>_meta.json— 视频元信息
文字稿格式(英文视频,中英对照):
# 视频标题
**频道**: xxx
**发布日期**: 2026-03-10
**时长**: 15:30
**原始链接**: https://www.youtube.com/watch?v=xxx
**转录语言**: en
---
## 文字稿(中英对照)
> 以下内容采用「英文原文 + 中文翻译」对照排列。
**[00:00]**
This is the original English text from the video...
这是视频中的中文翻译文本...
**[01:23]**
Next paragraph of English text...
下一段中文翻译...
Whisper 模型选择建议:
| 模型 | 速度 | 精度 | 适用场景 |
|---|---|---|---|
tiny |
最快 | 较低 | 快速预览、非关键内容 |
base |
快 | 中等 | 默认推荐,适合大部分场景 |
small |
中等 | 较高 | 口音较重、背景噪音较多 |
medium |
慢 | 高 | 重要内容、需要高精度 |
large |
最慢 | 最高 | 专业内容、学术演讲 |
Step 2:上传到乐享知识库
通过 lexiang MCP 工具完成上传,流程与 Step 2(普通文章转存乐享)一致。前提是 lexiang MCP 已连接(参见 Step 2 的「乐享 MCP 工具的调用方式」章节)。
文字稿上传(在线文档 page 类型):
- 获取知识库根节点 → 检查/创建日期目录(同上述步骤 1-3)
- 调用
entry_import_content(参数:space_id,parent_id=<日期目录ID>,name="<视频标题>",content=<文字稿Markdown内容>,content_type="markdown") - 在线文档支持后续在乐享中按块维度编辑更新(如修正翻译)
视频文件上传(file 类型,三步上传):
file_apply_upload(参数:parent_entry_id=<日期目录ID>,name="<视频标题>.mp4",size=<文件字节数>,mime_type="video/mp4",upload_type="PRE_SIGNED_URL")curl -X PUT "<upload_url>" -H "Content-Type: video/mp4" --data-binary "@<视频文件路径>"file_commit_upload(参数:session_id=<上一步返回的session_id>)
上传成功后:自动删除本地视频文件(rm -f <视频文件路径>),节省磁盘空间。
依赖:
yt-dlp(推荐brew install yt-dlp,不要用pip3 install)— YouTube 视频下载。必须用 brew 安装以获取最新版本,pip 版本受限于系统 Python 版本(如 Python 3.9 无法安装 nightly 版),而 brew 版自带独立 Python 环境openai-whisper(pip3 install openai-whisper)— 音频转录ffmpeg(brew install ffmpeg)— 音频提取openai(pip3 install openai)— 翻译(需要OPENAI_API_KEY环境变量)。如果没有 API Key,可以跳过翻译步骤,由 AI 助手直接在对话中翻译后更新文档
播客音频处理(yt-dlp + Whisper + 乐享)
当用户提供播客链接时(小宇宙FM xiaoyuzhoufm.com、Apple Podcasts 等),使用 yt-dlp 下载音频 + Whisper 转录的方式处理。
⚠️ 重要:yt-dlp 的 generic extractor 可以从播客页面中自动提取音频 URL(m4a/mp3),不需要 cookies,也不需要专门的播客 extractor。
工作流概述:
- yt-dlp 下载音频 → 本地
.m4a或.mp3文件(播客没有视频,直接是音频) - ffmpeg 提取/转换音频 → WAV 格式(16kHz 单声道,Whisper 推荐)
- Whisper 转录 → 带时间戳的文字稿
- 繁简转换(如需要)→ Whisper base 模型对中文会输出繁体,需用
opencc转为简体 - 上传乐享知识库(通过 lexiang MCP 工具):
- 文字稿:
entry_import_content创建为在线文档(page)格式 - 音频文件:
file_apply_upload→curl PUT→file_commit_upload三步上传
- 文字稿:
Step 1:下载音频
cd <项目子目录>
# yt-dlp 直接下载播客音频(不需要 cookies)
yt-dlp --no-playlist -o "%(title)s.%(ext)s" "<播客链接>"
小宇宙链接格式:
https://www.xiaoyuzhoufm.com/episode/<episode_id>yt-dlp 会通过 generic extractor 自动从页面中提取media.xyzcdn.net的音频直链。
Step 2:提取 WAV + Whisper 转录
# 提取 WAV(16kHz 单声道)
ffmpeg -i "<音频文件>.m4a" -vn -acodec pcm_s16le -ar 16000 -ac 1 -y "<音频文件>.wav"
# Whisper 转录(中文播客指定 language=zh)
python3 -c "
import whisper, json, time
model = whisper.load_model('base')
result = model.transcribe('<音频文件>.wav', language='zh', verbose=False)
with open('whisper_segments.json', 'w', encoding='utf-8') as f:
json.dump(result['segments'], f, ensure_ascii=False, indent=2)
print(f'Done: {len(result[\"segments\"])} segments')
"
Step 3:合并段落 + 繁简转换 + 生成 Markdown
使用与 YouTube 视频相同的段落合并逻辑(max_gap=2s, max_duration=60s)。
关键:Whisper base 模型对中文普通话倾向输出繁体字,必须用 opencc 进行繁简转换:
pip3 install opencc-python-reimplemented
import opencc
converter = opencc.OpenCC("t2s")
simplified_text = converter.convert(traditional_text)
文字稿 Markdown 格式(中文播客):
# 播客标题
**播客**: 节目名称
**平台**: 小宇宙FM
**时长**: 01:03:47
**原始链接**: https://www.xiaoyuzhoufm.com/episode/xxx
**转录语言**: zh
---
## 文字稿
**[00:00]** 第一段转录文本...
**[01:23]** 第二段转录文本...
Step 4:上传到乐享知识库
与 YouTube 视频处理相同的流程(通过 lexiang MCP 工具完成,前提是 MCP 已连接):
- 获取知识库根节点 → 检查/创建日期目录
- 文字稿使用
entry_import_content创建为在线文档(page 类型) - 音频文件使用三步上传流程(
file_apply_upload→curl PUT→file_commit_upload),注意 MIME 类型为audio/mp4(m4a)或audio/mpeg(mp3)
播客 vs YouTube 的关键区别:
| 维度 | YouTube 视频 | 播客音频 |
|---|---|---|
| 文件格式 | .mp4(视频) |
.m4a/.mp3(纯音频) |
| 文件大小 | 较大(HLS 720p ~500MB) | 较小(~60MB/小时) |
| 下载方式 | 需要 HLS 格式避免 403 | 直接下载,无反爬 |
| cookies | 通常需要 | 不需要 |
| Whisper 语言 | 通常是英文(需翻译) | 通常是中文(需繁简转换) |
| 上传 MIME | video/mp4 |
audio/mp4 或 audio/mpeg |
依赖(额外):
opencc-python-reimplemented(pip3 install opencc-python-reimplemented)— 繁体转简体(Whisper base 模型中文输出为繁体时需要)
结构化分析
输出结构化分析:
【文章主题】一句话概括
【核心论点】3-5 个关键观点
【关键数据】文章中的重要数据/图表
【利益相关】作者/机构的立场与潜在倾向(如有)
【原文出处】完整标题 + URL
规划图表:第 1 张为总览图,第 2-N 张各聚焦 1 个核心论点。向用户确认图表数量和主题划分。
Step 2:原文保存到乐享知识库
在进入信息图生成流程之前,先将原文完整保存到乐享知识库,确保素材归档和可追溯。
配置文件与初始化
本 skill 的目标知识库等信息通过配置文件管理,不在 SKILL.md 中硬编码。
配置文件路径:config.json(位于 skill 根目录,即与本 SKILL.md 同级)
对话式配置初始化(首次使用时自动触发)
当 config.json 中 _initialized 为 false 或 space_id 为空时,在执行任何乐享操作前,必须先通过对话引导用户完成配置。
核心设计:用户只需要粘贴一个乐享知识库链接,Agent 自动完成所有配置。
链接格式:https://<domain>/spaces/<space_id>?company_from=<company_from>
- 示例:
https://lexiangla.com/spaces/b6013f6492894a29abbd89d5f2e636c6?company_from=e6c565d6d16811efac17768586f8a025 - 从链接中可解析出三个关键信息:域名(
lexiangla.com)、space_id、company_from
流程如下:
第一步:检测 MCP 连接
- 尝试调用任意一个 lexiang MCP 工具(如
whoami)检测 MCP 是否已连接 - 如果调用成功 → MCP 已连接,进入第二步
- 如果调用失败(MCP 未连接)→ 引导用户完成 MCP 鉴权:
不要继续后续步骤,等待用户完成 MCP 连接后重试。⚠️ 乐享 MCP 尚未连接。请先完成鉴权配置: 1. 访问 https://lexiangla.com/mcp 登录后获取 COMPANY_FROM 和 LEXIANG_TOKEN 2. 按照你使用的 Agent 配置 MCP 连接: - CodeBuddy:在 MCP 管理面板中添加 lexiang server - OpenClaw:运行 claw install https://github.com/tencent-lexiang/lexiang-mcp-skill - 其他 Agent:在 MCP 配置文件中添加 lexiang server 3. 完成后告诉我,我会继续配置流程。
第二步:请求用户提供知识库链接
- 向用户发送引导消息:
🔧 首次使用,需要配置目标知识库。 请粘贴你想用来归档文章的乐享知识库链接,格式如: https://lexiangla.com/spaces/xxxxx?company_from=yyyyy 💡 获取方式:在乐享中打开目标知识库,复制浏览器地址栏中的链接即可。 - 等待用户输入,不要自行猜测或列举知识库
第三步:解析链接并验证
- 从用户提供的链接中用正则解析出三个字段:
- domain:链接的域名部分(如
lexiangla.com),用于生成后续访问链接 - space_id:
/spaces/后面的路径段(如b6013f6492894a29abbd89d5f2e636c6) - company_from:
company_from=参数值(如e6c565d6d16811efac17768586f8a025)
- domain:链接的域名部分(如
- 如果链接格式不正确(缺少
space_id或company_from)→ 提示用户重新粘贴正确的链接 - 调用
space_describe_space(参数:space_id=<解析出的 space_id>)验证知识库是否存在 - 如果验证失败 → 提示用户检查链接是否正确或是否有该知识库的访问权限
第四步:写入配置并确认
- 将解析和验证得到的信息写入
config.json:lexiang.target_space.space_id= 解析出的 space_idlexiang.target_space.space_name= 从space_describe_space返回值获取的知识库名称lexiang.target_space.company_from= 解析出的 company_fromlexiang.access_domain.domain= 解析出的域名lexiang.access_domain.page_url_template=https://<domain>/pages/{entry_id}lexiang.access_domain.space_url_template=https://<domain>/spaces/{space_id}?company_from={company_from}_initialized=true
- 向用户确认配置结果:
✅ 配置完成! 📚 目标知识库:<知识库名称> 🔗 访问链接:https://<domain>/spaces/<space_id>?company_from=<company_from> 后续抓取的文章将自动归档到此知识库。如需更换,告诉我「重新配置知识库」即可。
重新配置
当用户说「重新配置知识库」、「切换知识库」、「更换目标知识库」等类似意图时:
- 将
config.json中_initialized设为false - 重新执行上述对话式初始化流程(从第一步开始)
用户输入容错
用户可能不会粘贴完美的链接,需要处理以下情况:
| 用户输入 | 处理方式 |
|---|---|
完整链接 https://lexiangla.com/spaces/xxx?company_from=yyy |
直接解析 ✅ |
不带 company_from 的链接 https://lexiangla.com/spaces/xxx |
提示:「链接中缺少 company_from 参数。请在乐享中重新复制完整链接(地址栏中通常会包含 ?company_from=xxx),或者访问 https://lexiangla.com/mcp 获取你的 COMPANY_FROM 值告诉我。」 |
纯 space_id b6013f6492894a29abbd89d5f2e636c6 |
提示:「请提供完整的知识库链接(包含 company_from 参数),我需要从链接中同时获取知识库 ID 和企业标识。」 |
页面链接 https://lexiangla.com/pages/xxx |
提示:「这是一个页面链接,请提供知识库链接(格式:https://lexiangla.com/spaces/xxx?company_from=yyy)。你可以在乐享中进入目标知识库首页,复制地址栏链接。」 |
配置结构
{
"_initialized": false,
"lexiang": {
"target_space": {
"space_id": "",
"space_name": "",
"company_from": ""
},
"access_domain": {
"domain": "lexiangla.com",
"page_url_template": "https://lexiangla.com/pages/{entry_id}",
"space_url_template": "https://lexiangla.com/spaces/{space_id}?company_from={company_from}"
}
}
}
access_domain会从用户粘贴的链接中自动提取域名,无需手动配置。适配自定义域名的乐享部署。
后续文档中所有 <SPACE_ID>、<COMPANY_FROM>、<ACCESS_DOMAIN> 等占位符,均指从 config.json 中读取的实际值。
乐享 MCP 工具的调用方式(重要 — 多 Agent 适配)
本 skill 需要服务多个 Agent 产品(OpenClaw、CodeBuddy、Claude Desktop 等)。不同 Agent 连接乐享 MCP 的方式不同,但暴露的工具名称和参数完全一致(都是 lexiang MCP server 提供的标准工具)。
核心原则:本 skill 只描述「调用哪个工具 + 传什么参数」,不规定具体的 MCP 调用语法。每个 Agent 按自己的方式调用即可。
各 Agent 产品的 MCP 连接方式:
| Agent 产品 | lexiang MCP 连接方式 | 工具调用方式 |
|---|---|---|
| CodeBuddy | 在 ~/.codebuddy/mcp.json 中配置 lexiang server,通过 IDE 的 MCP 管理面板启用连接 |
直接调用 space_describe_space、file_apply_upload 等 lexiang MCP 工具 |
| OpenClaw | claw install https://github.com/tencent-lexiang/lexiang-mcp-skill,加载 skill 时自动连接 MCP |
同上,通过 skill 暴露的 MCP 工具调用 |
| Claude Desktop / 其他 MCP 兼容 Agent | 在 Agent 的 MCP 配置文件中添加 lexiang server URL | 同上 |
MCP 连接检测与降级:
在执行乐享操作前,必须先检测 lexiang MCP 是否已连接:
- 读取
config.json,检查_initialized和lexiang.target_space.space_id - 如果未初始化 → 先触发对话式配置初始化(参见上方「对话式配置初始化」),初始化流程中会自动完成 MCP 连接检测
- 如果已初始化,尝试调用
space_describe_space(参数:space_id=<config 中的 space_id>)验证 MCP 连接 - 如果调用成功 → MCP 已连接,继续后续流程
- 如果调用失败(MCP 未连接)→ 提示用户检查 MCP 连接,给出对应 Agent 的操作指引:
- CodeBuddy:「请在 MCP 管理面板中确认 lexiang server 已启用并显示为已连接状态」
- OpenClaw:「请确认已安装 lexiang skill(
claw install https://github.com/tencent-lexiang/lexiang-mcp-skill)」 - 其他 Agent:「请确认 MCP 配置中已添加 lexiang server」
⚠️ 禁止降级为 curl 调用 REST API:即使 MCP 未连接,也不要自行编写 curl 调用乐享 REST API,因为:(1) 认证信息硬编码在 curl 中不安全;(2) 不同 Agent 的执行环境差异大,curl 方式不通用;(3) REST API 的 URL 格式和鉴权方式可能变化。应该引导用户修复 MCP 连接。
认证配置(首次使用时需要):
访问 https://lexiangla.com/mcp 登录后获取
LEXIANG_TOKEN(访问令牌,格式:lxmcp_xxx)COMPANY_FROM无需手动获取 — 会从用户粘贴的知识库链接中自动解析配置方式(二选一):
- 环境变量(推荐):
export LEXIANG_TOKEN="lxmcp_xxx" - 直接修改 MCP 配置:将 MCP server URL 中的
${LEXIANG_TOKEN}占位符替换为实际值
- 环境变量(推荐):
详细配置步骤参见:lexiang-mcp-skill setup.md
目标知识库
从 config.json 的 lexiang.target_space 中读取:
- 知识库名称:
config.lexiang.target_space.space_name - 知识库访问链接:按
config.lexiang.access_domain.space_url_template格式拼接 - Space ID:
config.lexiang.target_space.space_id
⚠️ 访问链接域名:用户可访问的乐享前端域名从
config.lexiang.access_domain.domain读取(默认为lexiangla.com),不是mcp.lexiang-app.com(后者是 MCP API 服务端域名,浏览器无法直接访问)。所有展示给用户的链接必须按config.lexiang.access_domain.page_url_template格式生成。
目录组织方式
按天维度组织目录:
知识库根目录/
2026-02-25/
文章标题A.pdf (图文文章,文件上传)
文章标题B (纯文本文章,在线文档 page 类型)
2026-02-26/
文章标题C.pdf
操作流程
⚠️ 严格按步骤顺序执行,不得跳步! 必须完成步骤 0→1→2→3→4 的完整流程。尤其是步骤 2(创建日期目录)不可跳过——文档必须上传到当天日期命名的文件夹中,而不是直接上传到知识库根目录。如果跳过步骤 2 直接用
root_entry_id作为上传目标,文档将错误地出现在根目录下。
通过 lexiang MCP 工具,按以下步骤完成转存:
步骤 0:读取配置(含初始化检测)
- 读取 skill 目录下的
config.json文件 - 检查
_initialized是否为true且lexiang.target_space.space_id非空 - 如果未初始化(
_initialized为false或space_id为空)→ 触发对话式配置初始化流程(参见上方「对话式配置初始化」),完成后再继续 - 提取
lexiang.target_space.space_id、lexiang.access_domain.page_url_template等配置项
步骤 1:获取知识库根节点
- 调用
space_describe_space(参数:space_id=<config 中的 SPACE_ID>) - 从返回结果中提取
root_entry_id
步骤 2:检查/创建当天日期目录
- 调用
entry_list_children(参数:parent_id=<root_entry_id>)查询根目录下的子条目 - 查找是否已存在以当天日期命名(如
2026-03-18)的folder类型条目 - 如不存在,调用
entry_create_entry(参数:parent_entry_id=<root_entry_id>,name="2026-03-18",entry_type="folder")创建
步骤 3:去重检查
- 调用
entry_list_children(参数:parent_id=<日期目录ID>)查询该日期目录下已有的条目 - 按「名称 + 类型」检查是否已存在同名文档,如果已存在则跳过上传并告知用户
步骤 3.5:非中文文章翻译(⚠️ 不可跳过)
在上传到乐享之前,必须检测原文语言。如果原文不是中文,则需要先翻译为中英对照格式后再归档。
语言检测规则:
- 读取
<原文标题>.md的前 500 个字符,统计中文字符(Unicode 范围\u4e00-\u9fff)占比 - 中文字符占比 ≥ 30% → 判定为中文文章,跳过翻译,直接进入步骤 4
- 中文字符占比 < 30% → 判定为非中文文章,执行翻译
翻译排版格式(中英对照):
- 按段落逐段翻译,每段原文紧跟对应中文翻译
- 段落之间不加分隔线
---,仅通过空行分隔 - 中文翻译段落开头不加国旗 emoji(🇨🇳),直接以中文开始
- 标题也需要翻译,保留原文标题 + 中文翻译标题
- 列表项、引用块等结构元素同样逐条翻译
- 保留原文中的图片引用(
),图片引用放在对应段落的上方或下方,确保图文对应关系不丢失
# Original English Title
# 中文翻译标题
Original first paragraph text...
第一段的中文翻译...

Original second paragraph text...
第二段的中文翻译...
翻译方式(按优先级):
- translate_article.py 脚本(如果
OPENAI_API_KEY可用):python3 scripts/translate_article.py "<原文标题>.md" "<原文标题>_translated.md" --model gpt-4o-mini - AI 助手直接翻译(如果无 API Key):由 Agent 在对话中逐段翻译全文,生成
<原文标题>_translated.md
翻译完成后:
- 本地保存两个文件:
<原文标题>.md(原文)和<原文标题>_translated.md(中英对照版) - 归档到乐享知识库的必须是翻译后的中英对照版本(
_translated.md),确保知识库中的内容对中文读者友好 - 乐享文档标题使用:
<原文标题中文翻译>(<原文标题>),如:AI 原型精通阶梯(The AI Prototyping Mastery Ladder)
步骤 4:图文检测与上传
检查 <原文标题>.md 文件同目录下是否存在 images/ 目录且包含图片文件:
有图片(图文文章) → 先调用
scripts/md_to_pdf.py将 Markdown 转换为 PDF(嵌入图片),然后通过三步上传流程上传 PDF:file_apply_upload(参数:parent_entry_id=<日期目录ID>,name="<原文标题>.pdf",size=<文件字节数>,mime_type="application/pdf",upload_type="PRE_SIGNED_URL")- 使用
curl -X PUT将 PDF 文件上传到返回的upload_url(这是预签名 URL 直传 COS,不涉及认证信息) file_commit_upload(参数:session_id=<上一步返回的session_id>)
无图片(纯文本文章) → 使用
entry_import_content创建为在线文档(page 类型):- 参数:
space_id=<config 中的 SPACE_ID>,parent_id=<日期目录ID>,name="<原文标题>",content=<Markdown文件内容>,content_type="markdown" - 在线文档支持在乐享中直接编辑
- 参数:
步骤 5:输出结果
- 按
config.json中的lexiang.access_domain.page_url_template格式拼接文档链接,告知用户 - 示例:
https://lexiangla.com/pages/<entry_id>(域名从配置读取,不要硬编码)
注意事项
- 配置初始化是前置条件:首次使用时会自动通过对话引导完成知识库配置,无需手动编辑文件
- MCP 连接是前置条件:必须先确认 lexiang MCP 已连接才能执行操作。不同 Agent 的连接方式不同,参见上方「乐享 MCP 工具的调用方式」
- 访问链接域名:展示给用户的链接一律按
config.json中page_url_template格式生成,不要使用mcp.lexiang-app.com - 上传前自动去重:按「文档名称 + 文档类型」在目标日期目录下查重,避免重复上传
- 图文文章自动转为 PDF 上传(嵌入图片),确保知识库中保留完整图文信息
- 纯文本文章以**在线文档(page)**格式创建,可在乐享中直接编辑
- PDF 转换依赖
pymupdf库(pip3 install pymupdf),如未安装则回退为在线文档方式上传 Markdown - 如果同一天多次处理不同文章,它们会归入同一个日期目录下
- 使用
_mcp_fields参数可以减少返回数据量,如_mcp_fields=["id", "root_entry_id", "name"]
脚本文件
| 文件 | 用途 |
|---|---|
scripts/fetch_article.py |
付费/登录墙文章全文抓取脚本(Chrome cookies + Playwright,Substack 登录态缓存,输出 Markdown + 图片 + 元信息 JSON) |
scripts/md_to_pdf.py |
Markdown 转 PDF 脚本(使用 pymupdf,嵌入本地图片,正确渲染中文,支持标题回退和拆行标题修复) |
scripts/yt_download_transcribe.py |
YouTube 视频下载 + Whisper 转录 + AI 翻译脚本(yt-dlp 下载、ffmpeg 提取音频、Whisper 转录、OpenAI 翻译为中英对照 Markdown)。也可用于播客音频转录(跳过视频下载步骤) |
注意:乐享知识库操作不再通过独立脚本(
save_to_lexiang.sh/upload_yt_to_lexiang.sh)完成,而是由大模型通过 lexiang MCP 工具直接执行。不同 Agent 产品(OpenClaw、CodeBuddy、Claude Desktop 等)各自管理 MCP 连接,但调用的工具名称和参数完全一致。
经验总结
YouTube 视频下载与转录
核心方案:yt-dlp 下载 → ffmpeg 提取音频 → Whisper 本地转录 → OpenAI API 翻译
为什么不用 NotebookLM / summarize.sh:
- NotebookLM 需要 Google 账号且有额度限制,部分视频可能因版权限制无法提取
- summarize.sh 依赖外部 API(Apify/YouTube 字幕 API),部分视频无字幕时无法工作
- Whisper 本地转录不依赖字幕,直接从音频波形识别语音,覆盖率 100%
yt-dlp 版本与安装(关键!):
- 必须使用
brew install yt-dlp安装,不要用pip3 install yt-dlp - 原因:pip 版本受限于系统 Python 版本(macOS 自带 Python 3.9),无法安装 yt-dlp 的 nightly 版本(需要 Python 3.10+)。而 YouTube 频繁更新反爬策略,旧版 yt-dlp 会遇到 HTTP 403 Forbidden 错误
- brew 安装的 yt-dlp 自带独立 Python 环境,始终能获取最新版本
- 脚本中调用方式:直接用
yt-dlp命令,不要用python3 -m yt_dlp
YouTube DASH 格式 403 错误(重要!):
- YouTube 正在强制使用 SABR(Streaming ABR)流媒体协议,传统 DASH 分片下载(
bestvideo+bestaudio)会触发 HTTP 403 Forbidden - 解决方案:优先使用 HLS(m3u8)格式下载,不会被 SABR 拦截
- 脚本中的格式选择顺序:
95-1/94-1/93-1/bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best95-1: 720p HLS(推荐,画质和文件大小的最佳平衡)94-1: 480p HLS93-1: 360p HLS- 后面是传统 DASH 格式作为回退
- HLS 格式下载的视频文件会比 DASH 大一些(720p HLS 约 500-600MB vs DASH 约 200-300MB)
- 注意:
--extractor-args "youtube:player_client=android"不支持 cookies,不是可靠的 403 解决方案
Whisper 转录最佳实践:
- 音频预处理:16kHz 采样率、单声道 WAV(
ffmpeg -ar 16000 -ac 1),减少文件大小且是 Whisper 推荐格式 - 段落合并策略:相邻 segment 间隔 <2s 且总时长 <60s 则合并,句号/问号结尾时倾向断开
- 模型选择:默认用
base(速度和精度的最佳平衡),重要内容用small或medium
翻译策略:
- 使用 OpenAI
gpt-4o-mini,分批翻译(每批 10 段),避免 token 超限 - 翻译 prompt 要求"自然流畅的中文表达,专业术语保留英文并附中文注释"
- 中英对照格式:每段先展示英文原文,紧跟中文翻译,段间用空行分隔(不加分隔线和国旗 emoji)
- 如果没有 OPENAI_API_KEY:脚本会跳过翻译步骤,输出纯英文文字稿。此时可以由 AI 助手在对话中直接翻译全文,然后用
md_to_page.py --entry-id更新乐享文档
上传乐享的关键决策:
- 文字稿使用 在线文档(page)格式而非文件上传,原因:支持在乐享中按块维度编辑更新,可以逐段修正翻译或补充注释
- 视频使用 文件(file)格式上传,因为视频不需要在线编辑
- 上传成功后自动删除本地视频文件,避免占用磁盘空间
视频上传到乐享的正确方式(重要!):
- 通过 lexiang MCP 工具完成,使用三步上传流程:
file_apply_upload:申请上传凭证(传入parent_entry_id=日期目录 ID、upload_type=PRE_SIGNED_URL、mime_type=video/mp4、size=文件字节数)curl -X PUT上传文件到返回的upload_url(预签名 URL,直传 COS)file_commit_upload:确认上传完成(传入session_id)
- 518MB 视频的 PUT 上传约需 30-60 秒
播客音频转录
核心方案:yt-dlp(generic extractor)下载音频 → ffmpeg 转 WAV → Whisper 转录 → opencc 繁简转换
yt-dlp 对小宇宙的支持:
- yt-dlp 没有小宇宙专用 extractor,但 generic extractor 完全够用
- 小宇宙页面中嵌入了
<audio>标签,音频直链在media.xyzcdn.net - 下载不需要 cookies,直接用
yt-dlp --no-playlist -o "%(title)s.%(ext)s" <URL>即可 - 下载速度约 7MB/s,63 分钟播客(59MB)仅需 8 秒
Whisper 中文转录的繁体问题(重要!):
- Whisper base 模型对中文普通话倾向输出繁体字(如「歡迎」→ 应为「欢迎」)
- 这是 Whisper 的已知行为,因为训练数据中繁体中文比重较大
- 解决方案:转录后用
opencc-python-reimplemented的t2s(Traditional to Simplified)模式批量转换 - 安装:
pip3 install opencc-python-reimplemented - 用法:
opencc.OpenCC("t2s").convert(text)
中文播客 vs 英文 YouTube 的流程差异:
- 中文播客不需要翻译,但需要繁简转换
- 播客音频是直接的 m4a/mp3 文件,不需要从视频中提取音频(但仍需 ffmpeg 转为 WAV 格式给 Whisper)
- Whisper 转录时指定
language='zh'可以提高中文识别准确率 - 上传乐享时 MIME 类型用
audio/mp4(m4a)或audio/mpeg(mp3),不是video/mp4
转录性能参考:
- 63 分钟中文播客 → Whisper base 模型在 CPU 上转录耗时约 115 秒
- 产出 2496 个 segments,合并后 65 个段落
微信公众号图文抓取
核心问题:web_fetch 工具无法获取微信公众号文章的图片(懒加载 + 防盗链),必须使用 fetch_article.py。
技术原理:
- 懒加载机制:微信图片的真实 URL 存放在
data-src而非src,依赖IntersectionObserver在元素进入视口时才加载。Playwright 无头浏览器通过window.scrollBy(0, 300)配合asyncio.sleep(0.2)模拟慢速滚动,逐步触发所有图片的懒加载观察器 - 兜底策略:滚动完成后,通过
page.evaluate()遍历所有img[data-src],将未被触发的data-src强制复制到src - 高清图优先:提取图片 URL 时优先使用
data-src(高清原图),而非src(可能是低分辨率占位图) - 格式识别:微信图片 URL 无常规扩展名(如
mmbiz.qpic.cn/...?wx_fmt=png),需解析wx_fmt查询参数推断文件格式 - 防盗链绕过:通过 Playwright 页面上下文的
page.request.get()下载图片,自动携带正确的 Referer 头 - 专用选择器:微信文章有固定 DOM 结构(
#js_content、#activity-name、#js_name、#publish_time),使用专用选择器比通用选择器更精准可靠
关键决策:
- 微信文章是公开可读的,跳过登录检测和 Cookie 注入流程
- 滚动参数(300px 步长、200ms 间隔)经实测可平衡速度与懒加载触发成功率
- Markdown 转换时
imageMap同时匹配src和data-src,确保无论 HTML 中引用哪个属性都能正确替换
验证标准:抓取完成后检查 article_meta.json 中的 image_count 字段,与原文图片数量比对,确认无遗漏。
新平台适配思路
适配新平台时,需依次识别和处理以下 4 个维度:
- 懒加载机制 — 图片是否用
data-src、data-lazy等延迟加载?需要怎样的滚动策略触发? - 专用 DOM 结构 — 正文、标题、作者、日期的选择器是什么?
- 图片 URL 格式 — 扩展名是否在路径中?是否需要从查询参数推断?
- 防盗链策略 — 是否需要正确的 Referer?是否有其他鉴权机制?
得到 APP 文章抓取(dedao.cn)
核心问题:得到 APP(www.dedao.cn)的文章内容是付费内容 + SPA 动态渲染,web_fetch 和 fetch_article.py 的通用提取逻辑都无法直接获取正文。
技术原因:
- SPA 架构:得到网页版是 React SPA,文章正文通过 JS 异步渲染,
web_fetch只能拿到空白壳页面 - 付费墙:文章属于付费专栏内容,必须有已登录且已订阅的账号才能查看全文
- DOM 结构特殊:正文容器使用
.iget-articles类名,不在fetch_article.py的默认选择器列表(article、.post-content等)中。通用article选择器只匹配到极少内容(~167 字符),而真正的正文在.iget-articles中有 6000+ 字符 - 内容区混杂:正文容器中混入了标题重复、音频时长、"划重点"、用户评论等非正文内容,需要清理
抓取方案:使用 CDP 模式连接已登录得到的 Chrome 浏览器:
# 前提:用户已在 Chrome 中登录得到 APP 且有文章阅读权限
python scripts/fetch_article.py fetch "https://www.dedao.cn/course/article?id=<ID>" --output-dir <目录> --cdp
已知限制:
fetch_article.py的通用内容提取逻辑对得到 DOM 结构匹配不佳,抓取结果可能不完整- 正确做法是通过 Playwright CDP 连接后,手动指定
.iget-articles选择器提取正文:
# 通过 CDP 连接后,用专用选择器提取得到文章正文
content_el = await page.query_selector('.iget-articles')
if content_el:
text = await content_el.inner_text() # 完整正文
内容清理要点:
- 去掉正文开头的标题重复、日期、音频时长等元信息(通常在
凡哥杂谈,你好或类似开场白之前) - 去掉正文末尾的"划重点"、"添加到笔记"、"首次发布"、"用户留言"等非正文内容
- 如果是多篇系列文章(如上/下篇),合并时用
## 上篇/## 下篇分隔 - 作者信息需要手动确认(通用提取器可能抓错)
适用场景:得到 APP 专栏文章(www.dedao.cn/course/article?id=xxx)
TODO:考虑在 fetch_article.py 中增加得到专用检测和选择器(类似微信公众号的 _is_wechat_article 机制),自动使用 .iget-articles 提取正文。
Python 兼容性
脚本使用 from __future__ import annotations 以兼容 Python 3.9(str | None 联合类型语法在 3.9 中不可用)。
常见问题
| 问题 | 原因 | 修复方法 |
|---|---|---|
| YouTube 视频下载 HTTP 403 Forbidden | yt-dlp 版本过旧 + YouTube 强制 SABR 流媒体协议,传统 DASH 分片下载被拦截 | ① brew install yt-dlp 升级到最新版(不要用 pip);② 脚本已配置优先使用 HLS(m3u8) 格式(95-1/94-1/93-1),自动回退 |
pip3 install --upgrade yt-dlp 无法安装最新版 |
macOS 自带 Python 3.9,yt-dlp nightly 版需要 Python 3.10+ | 改用 brew install yt-dlp,brew 版自带独立 Python 环境 |
脚本中 python3 -m yt_dlp 调用失败 |
pip 安装的旧版 yt-dlp 与 brew 安装的新版不一致 | 脚本已修改为直接调用 yt-dlp 命令(brew 安装的版本) |
| 视频上传乐享报"不支持的文件格式" | 旧版 COS API(/kb/files/upload-params)不识别视频格式 |
通过 lexiang MCP 工具使用三步上传流程:file_apply_upload → curl PUT → file_commit_upload |
| Whisper 转录速度极慢 | 模型太大或音频太长 | 换用 tiny 或 base 模型;对于长视频(>1h),考虑用 --whisper-model tiny 先快速预览 |
| 翻译结果为空 | 未设置 OPENAI_API_KEY 环境变量 |
export OPENAI_API_KEY=sk-xxx;或使用 --skip-translate 跳过翻译,由 AI 助手在对话中直接翻译全文后用 md_to_page.py --entry-id 更新乐享文档 |
| 中英对照格式段落错位 | AI 翻译返回的段落数与原文不匹配 | 脚本已有容错处理(缺少翻译的段落会跳过),可手动补充翻译 |
| 视频上传乐享超时 | 视频文件过大(>500MB) | 使用 MCP 的 file_apply_upload 预签名 URL 方式上传,518MB 文件约 30-60 秒即可完成 |
| Whisper 中文转录输出繁体字 | Whisper base 模型对中文普通话倾向输出繁体 | 用 opencc-python-reimplemented 的 t2s 模式进行繁简转换:opencc.OpenCC("t2s").convert(text) |
| 小宇宙播客下载提示 generic extractor | yt-dlp 没有小宇宙专用 extractor | 正常现象,generic extractor 能自动从页面提取音频直链(media.xyzcdn.net),下载完全正常 |
| 微信文章图片丢失 | web_fetch 无法触发懒加载和绕过防盗链 |
必须使用 fetch_article.py,脚本自动检测微信域名并启用专用处理策略 |
| 乐享知识库操作失败 | MCP 连接异常或 Token 过期 | ① 确认当前 Agent 的 lexiang MCP 已连接(CodeBuddy 检查 MCP 面板、OpenClaw 检查 skill 安装状态);② Token 过期时访问 https://lexiangla.com/mcp 获取新 Token 并更新 MCP 配置 |
| 文件上传到了知识库根目录而非日期目录 | 跳过了步骤 2(创建日期目录)和步骤 3(去重检查),直接以 root_entry_id 作为 parent_entry_id 上传 |
严格按照步骤 1→2→3→4 顺序执行,步骤 2 中先 entry_list_children 检查日期目录是否存在,不存在则创建 |
| 展示给用户的乐享链接无法访问 | 使用了 MCP API 域名 mcp.lexiang-app.com 而非用户可访问的前端域名 |
所有展示给用户的链接必须按 config.json 中 page_url_template 格式生成(默认为 https://lexiangla.com/pages/<entry_id>) |
| PDF 中缺少标题 | fetch_article.py 的 processNode 将正文 <h1> 转为 # 标题,与手动拼接的元信息头标题重复;某些网站(如 Lenny's Newsletter)标题在 articleEl 外部导致 MD 文件第一行 # 为空 |
已修复:(1) processNode 中自动去重正文中与已提取 title 相同的第一个 h1 (2) 标题提取增加 og:title、meta[name="title"]、document.title 多策略回退 (3) md_to_pdf.py 增加标题回退——当 MD 中无有效 h1 时从 article_meta.json 补充 |
| PDF 中缺少子标题 | 某些网站的 HTML 结构导致 ### # 从 Tab 到 Agents 被拆为两行:### # 和 从 Tab 到 Agents,parse_markdown 将 # 视为无效标题丢弃 |
已修复:parse_markdown 增加拆行标题检测——当标题文字为 # 或空时,检查下一行是否为实际标题文字并合并 |
Version History
Latest version: 0.1.2
First published: Mar 18, 2026. Last updated: Mar 30, 2026.
2 versions released.
Frequently Asked Questions
Is Fetch Archive to Lexiang free to use?
What platforms does Fetch Archive to Lexiang support?
How do I update Fetch Archive to Lexiang?
openclaw skills update fetch-archive-to-lexiang to get the latest version. OpenClaw will download and apply the update automatically, preserving your existing configuration.