用 Doubao-Seed-Evolving + Python 免费制作网页正文提取工具(实战教程)
一、技术选择与需求界定
目标:去掉导航/广告/侧边栏并生成正文 Markdown,只需输入一个网页 URL。
选型:
- readability(readability-lxml)做正文去噪
- markdownify 把清洗后的 HTML 转 Markdown
- 预清理由 BeautifulSoup 承担
- 客户端渲染站点交给 Playwright
Doubao-Seed-Evolving 在一次对话中生成了初版代码,下面整理其中的关键实现和实际踩坑。
二、首版实现
这是我输入提示词后AI给的回答:
节选出的核心结构是这样:
import requestsfrom bs4 import BeautifulSoupfrom readability import Documentimport markdownify as mdDEFAULT_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."def fetch_url(url, timeout=15, verify_ssl=True):if not url.startswith(("http://", "https://")):url = "https://" + urlheaders = {"User-Agent": DEFAULT_UA}resp = requests.get(url, headers=headers, timeout=timeout, verify=verify_ssl)resp.raise_for_status()return resp.textdef extract_markdown(html, page_url=""):soup = BeautifulSoup(html, "lxml")for tag in soup.find_all(["script", "style", "nav", "aside", "footer"]):tag.decompose()doc = Document(str(soup), url=page_url)content_html = doc.summary()return md(content_html, heading_style="ATX", convert=["table", "pre"])
注意:第一版有个坑——markdownify 不能同传 convert 和 strip,否则运行时直接报错。预清理已处理 script/style,所以删掉 strip 即可。这个修复也是模型在看到报错后给出的。
三、三类网站实测
测试结果如实记录如下,样本是 3 个类型不同的网页:
| 网站类型 | 结果 | 现象 |
|---|---|---|
| SSR 类技术博客 | ✅ | 表格与代码块均未丢失,语言标注也完整保留 |
| 公众号 | ⚠️ | 标题成为 [no-title],正文则为 OK |
| 头条(CSR) | ❌ | 正文没有内容,仅剩 [no-title] |
第一版的表现并没有框架预设中那么糟糕,却暴露了比预设更有意思的真实问题:不同网站各自显现出不同短板。三个网页的结果分别是直接成功、标题丢失和只剩空壳。
四、关键修复一:标题提取的退化问题
og:title 不在 readability-lxml 的 Document.summary() 读取范围内,它只取 <title>。解析 bug 会被微信文章的标题格式触发,结果为 [no-title]。
修复:先执行一层语义化标题提取,再进入 extract_markdown。
def extract_title(soup, doc):og = soup.find("meta", property="og:title")if og and og.get("content"):return og["content"].strip()tw = soup.find("meta", attrs={"name": "twitter:title"})if tw and tw.get("content"):return tw["content"].strip()h1 = soup.find("h1")if h1 and h1.get_text(strip=True):return h1.get_text(strip=True)return doc.short_title()
五、关键修复二:客户端渲染站点的空壳
头条这类站点正文由 JS 异步加载,requests 拿到的只是 <div id="root"> 空壳。
修复:新增 --render 参数,提取操作放到 Playwright 无头浏览器完成渲染之后。
from playwright.sync_api import sync_playwrightdef fetch_rendered(url):with sync_playwright() as p:browser = p.chromium.launch(headless=True)page = browser.new_page()page.goto(url, wait_until="networkidle")html = page.content()browser.close()return html
另:微信/头条图片是懒加载,真实地址在 data-src,需补一段把 data-src 回填到 src,否则全文裂图。
六、最终使用方法
python extract_article.py https://juejin.cn/post/xxx -o article.mdpython extract_article.py https://www.toutiao.com/xxx --render -o toutiao.md
静态站不需要额外依赖,动态站加 --render。
-
07.29
《幻兽帕鲁》工作帕鲁配置实用攻略
-
07.29
《猎国ol》国战不仅能冲锋,六种PK模式开启不同玩法
-
07.29
三界漫漫,知己难寻《西游3》与志同道合的好友并肩西行
-
07.29
天马祈福开启《全球使命3》共赴神器星愿盛宴
-
07.29
《大航海时代:凯旋航线》“启航测试”今日15点扬帆开启
-
07.29
遗忘之海摇滚螃蟹实战打法指南
-
-
下载
- |
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- |
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏