最稳妥的标题提取是先取soup.title.string再校验h1等标签;正文需先定位article/main等容器再get_text;动态内容需检查JS渲染特征;lxml解析器比html.parser更高效容错。

用 BeautifulSoup 的 soup.title.string 提取标题最稳妥
标题通常在 <title></title> 标签内,但注意:有些页面的 <title></title> 是网站名(如“知乎 - 有问题,就会有答案”),而非文章标题。真正内容标题往往在 <h1></h1> 或带特定 class 的元素里。
推荐分两步校验:
- 先取
soup.title.string,strip() 后非空则暂存 - 再用
soup.find('h1')或常见标题选择器(如soup.select('article h1, .post-title, [itemprop="headline"]'))尝试提取;若存在且文本长度合理(比如 >5 字符),优先采用 - 避免直接用
soup.h1——它只返回第一个<h1></h1>,且当不存在时返回None,调用.string会报AttributeError
soup.get_text() 不适合直接提取正文,得先定位主体区域
全量调用 soup.get_text() 会把导航栏、页脚、广告脚本等全部混在一起,噪声极大。真实场景中必须先收缩作用域。
常见做法是:
立即学习“前端免费学习笔记(深入)”;
- 用
soup.find('article')或soup.find('main')——现代语义化 HTML 通常把正文包在这类标签里 - fallback 到 CSS 类名:如
soup.select('.content, .post-body, #primary'),取第一个非空结果 - 对选中的容器元素调用
.get_text(separator='\n', strip=True),其中separator='\n'能保留段落换行,比默认空格更符合阅读习惯 - 若目标站点结构固定,可提前过滤掉不需要的子节点,例如:
for tag in container(['script', 'style', 'nav', 'footer']): tag.decompose()
遇到动态渲染内容时,requests + BeautifulSoup 会漏掉标题和正文
很多新闻或博客站点用 JavaScript 渲染标题和正文(比如 React/Vue 驱动的页面),requests.get(url).text 拿到的是初始 HTML 骨架,关键内容在后续 AJAX 请求或客户端 JS 中生成。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
这时不能硬扛:
- 先检查响应中是否含
id="app"或data-server-rendered="true"等 SSR/CSR 特征 - 查看 Network 面板,找 XHR/Fetch 请求,看正文数据是否来自 JSON API(如
/api/article/123),直接请求那个接口更高效 - 万不得已才上无头浏览器(如 Playwright),但开销大、启动慢、易被风控;
requests+BeautifulSoup应该是默认首选,仅当确认内容静态可得时才用
lxml 解析器比 html.parser 更快更容错,但需额外安装
默认的 html.parser 是 Python 内置,无需安装,但解析不规范 HTML(如缺失闭合标签、属性没引号)时容易丢节点或结构错乱。
lxml 是工业级选择:
- 解析速度通常快 3–5 倍,尤其对大文档
- 自动修复常见 HTML 错误,比如把
<p>hello</p> <div>world 补全为合法嵌套<li>安装命令是 <code>pip install lxml,使用时显式指定:BeautifulSoup(html_content, 'lxml') - 注意:Windows 用户若 pip 安装失败,可改用
conda install lxml或下载预编译 wheel
实际提取逻辑中,最容易被忽略的是「标题与正文来源不一致」:标题可能在 <meta property="og:title"> 里,正文可能藏在 __NEXT_DATA__ 脚本中。这类情况没有银弹,得结合具体站点源码结构做适配,而不是套一个通用函数就完事。


















