技术博客
链接读取的 output 到底是什么格式:Markdown 结构拆解与二次处理

链接读取的 output 到底是什么格式:Markdown 结构拆解与二次处理

作者: 万维易源
2026-09-15
链接读取Markdown返回格式正文清洗文本处理
# 链接读取的 output 到底是什么格式:Markdown 结构拆解与二次处理 接口:链接读取(apiCode=3262)· 接入点:获取网页正文(3262-1)· 计费:50 厘/次 · 适用人群:要拿正文做下游处理的开发者 · 阅读时间:约 10 分钟 · 最后实测核对:2026-09-15 ## 核心要点 - 文档把 `output` 写成 `String`,实测它返回的是 **Markdown**:标题、列表、表格、图片、链接都带结构。 - 图片的 `alt` 是一串哈希,链接有时指向栏目页而不是图片文件,直接拿去做图集会出错。 - 正文里混着导航和页脚,入库前必须清洗,否则检索结果会被垃圾文本污染。 ## 拿到的是一份带结构的正文 第一次看到 `output` 的人通常会愣一下。文档写的是 `String`,你以为是一段纯文本,实际拿到的是这样(站点与页面正文已隐去,只保留结构): ```markdown # 页面主标题 导航项 导航项 导航项 榜单名 条目一 条目二 条目三 条目四 条目五 功能入口 更多 ``` 再看另一个站点首页返回的片段(同样只保留结构): ```markdown ### 栏目下的一条标题 摘要文字…… ## <br> 栏目名 ![6f2a1c8b9d4e0f37-8b2f5a1c9e4d7a03](https://<站点域名>/<栏目路径>/) - 条目名 - 条目名 ``` 这两段放一起看,能看出这个接口做的事:把页面 DOM 里的文本层级翻译成 Markdown 语法。转得挺合理,但也留下了原页面的痕迹。 ## `output` 里实际出现的六类结构 | 结构 | 语法形态 | 实测例子(内容已隐去) | 备注 | |------|---------|---------------------|------| | ATX 标题 | `#` / `##` / `###` | `# 页面主标题`、`### 栏目下的一条标题` | 层级来自原页面的 h1/h2/h3 | | 无序列表 | `- ` | `- 条目名` | 导航、栏目名大量使用 | | 有序列表 | `1. ` | `1. 栏目名`、`1. 榜单名` | 综合门户首页实测出现 | | 管道表格 | `\| --- \| --- \|` | 新闻站点首页的频道表 | 表格被完整转成 Markdown 表格 | | 图片 | `![alt](url)` | ` ![<32 位哈希串](https://…/<路径>)` | alt 是哈希串,不是描述文字 | | 链接 | `[text](url)` | `[联系邮箱: xxx@example.com](mailto:xxx@example.com)` | 会出现 `mailto:` 等协议 | 另外还有加粗 `**加粗文字**`、以及**残留的原始 HTML 标签**——上面那段里就有 `## <br> 栏目名`,`<br>` 没被清掉。 ## 几种需要二次处理的写法 **图片的 `alt` 是哈希,不是图片说明。** `![6f2a1c8b9d4e0f37-8b2f5a1c9e4d7a03]` 这串东西对读者和模型都没意义。要用图片,得自己生成描述,或者干脆放弃 `alt`。 **图片链接有时指向公开网页,不是图片文件。** 实测里有条图片语法的 URL 实际是一个视频栏目的页面地址,不是图片文件。照着 `output` 里的图片地址去下载文件,会拿到一堆 HTML。判断办法是看扩展名和 `Content-Type`,不能只看 `![]()` 这个语法。 **导航和页脚混在正文里。** 实测某个垂直站点的首页只返回 850 字符,其中大半是"查公司 / 查老板 / 快捷功能 / 关于我们"这类导航项。这不是接口侧的问题,而是首页本身就以导航为主。做检索之前需要把这类短行切掉。 **段落被拆得很碎。** 原文里一个换行,`output` 里往往变成 `\n\n`,于是每个短句都成了一个独立段落。直接按段落切块,会切出一堆长度只有十几个字的碎片。 ## 四种后处理写法 ### 转 HTML 直接渲染 ```python # pip install markdown import markdown html_body = markdown.markdown(output, extensions=["tables", "fenced_code"]) html = f"<!doctype html><html><head><meta charset='utf-8'></head><body>{html_body}</body></html>" ``` `tables` 扩展必须开,否则管道表格会渲染成一堆竖线。 ### 转纯文本 ```python # pip install markdown-it-py from markdown_it import MarkdownIt import re def to_plain_text(md: str) -> str: tokens = MarkdownIt("commonmark").parse(md) parts = [] for t in tokens: if t.type == "inline" and t.content: parts.append(t.content) elif t.type in ("fence", "code_block"): parts.append(t.content) text = "\n".join(parts) text = re.sub(r"!\[[^\]]*\]\([^)]*\)", "", text) # 去图片 text = re.sub(r"\[([^\]]*)\]\([^)]*\)", r"\1", text) # 链接保留文字 return text ``` ### 抽图片地址 ```python import re IMG_RE = re.compile(r"!\[([^\]]*)\]\(([^)\s]+)") def extract_images(md: str): """返回 [(alt, url)]。注意 url 可能指向页面而非图片文件,需下游校验。""" return IMG_RE.findall(md) ``` 拿到列表后别急着下载,先按扩展名过滤一遍,`Content-Type` 也要查。 ### 按标题切分块 ```python import re def chunk_by_heading(md: str, min_len: int = 120): """按 Markdown 标题切块;过短的块与下一块合并,避免碎片。""" lines = md.splitlines() chunks, cur_title, cur_buf = [], "(无标题)", [] def flush(title, buf): text = "\n".join(buf).strip() if not text: return if chunks and len(text) < min_len: chunks[-1]["text"] += "\n" + text # 太短就并进上一块 else: chunks.append({"title": title, "text": text}) for ln in lines: m = re.match(r"^(#{1,6})\s+(.*)$", ln) if m: flush(cur_title, cur_buf) cur_title, cur_buf = m.group(2).strip(), [] else: cur_buf.append(ln) flush(cur_title, cur_buf) return chunks ``` `min_len` 设 120 左右,是为了对付上面说的"段落被拆碎"问题。实测下来,不合并的话,门户首页能切出上百个只有十几个字的块,检索命中率会很难看。 ## 清洗规则建议 放到向量库之前,这几条按顺序过一遍: - 删掉长度小于 6 个字且不含标点的行——导航项基本都是这个形状 - 删掉连续重复的行(页面轮播、榜单常有重复) - 合并连续空行,把 3 个以上 `\n` 压成 2 个 - 去掉独立的 `[...](...)` 行——纯链接行对检索没帮助 - 保留标题,它是切块时唯一可用的层级信息 要不要在这一步做正文提取(也就是从整页里挑出主体段落),取决于你的数据源。新闻详情页本身干净,门户首页就得靠上面的规则削。 ## FAQ **Q1:`output` 是 JSON 还是 Markdown?** 是 Markdown 文本,装在 `showapi_res_body.output` 这个字符串字段里。外层是 JSON,正文本身是 Markdown。 **Q2:为什么图片的 `alt` 是一串乱码?** 那不是乱码,是原页面图片节点的标识符,接口原样保留了下来。它不含语义信息,做展示或检索时建议忽略,或者自己根据上下文补描述。 **Q3:表格能保留吗?** 能。实测某个新闻站点首页返回的频道表被完整转成了 Markdown 管道表格,用 `markdown` 库渲染时带上 `tables` 扩展就能正确显示成表格。 **Q4:`output` 里有 HTML 标签,正常吗?** 正常。实测出现过 `## <br> 锋面` 这种,`<br>` 是原页面的换行标签,没有被清理。入库前顺手过滤一遍 `<[^>]+>` 就行。 **Q5:正文里的导航怎么去掉?** 没有通用的一刀切办法。可行的做法是结合长度和标点做启发式过滤:导航项通常很短、不含句末标点、且成组出现。上面的清洗规则里第 1 条就是干这个的。 ## 下一步阅读 - 把这些块喂进向量库的完整管道 → [把链接读取接进 RAG 管道](https://www.showapi.com/guides/link-read-rag-pipeline-3262) - `output` 的取值与结果判断 → [链接读取返回结构说明与结果判断](https://www.showapi.com/guides/link-read-empty-output-3262) - 第一次调用还没跑通 → [链接读取:用 Python 读取任意公开网页的正文](https://www.showapi.com/guides/link-read-quickstart-3262) - **本系列共 6 篇**:查看[链接读取指南总目录](https://www.showapi.com/guides/link-read-guides-3262)