浏览器构建dom树而非直接提供文档字符串,提取内容需通过document api查询节点获取innertext、innerhtml或属性值,注意判空、xss风险及动态渲染影响。

浏览器本身不“读取文档内容”供你直接拿字符串用,它构建的是 DOM 树;你要提取内容,得基于这个树结构去查节点、取文本或 innerHTML —— 不是解析引擎在帮你“读”,是你在用 JS 或服务端库去“问”它要什么。
浏览器里用 document API 提取标题、正文、描述
这是最常见也最容易出错的场景:想拿 <title></title>、<meta name="description">、 里的纯文本。但注意:
-
document.title是最稳的,它始终返回<title></title>的文本内容(自动去标签、解码) -
document.querySelector('meta[name="description"]')可能返回null,必须判空再取.getAttribute('content') -
document.body.textContent会把所有脚本、样式、注释里的文字也拼进去,不是“正文”而是“所有可见文本” - 如果页面用了 SSR 或动态渲染,
document.body.innerHTML才反映当前真实 HTML 结构,textContent无法还原标签语义
Python 用 BeautifulSoup 解析本地或响应 HTML
服务端或爬虫场景下,你拿到的是原始 HTML 字节流,BeautifulSoup 是最容错的选择,但它对编码和解析器很敏感:
- 永远优先用
response.content(bytes)而非response.text初始化BeautifulSoup,否则 UTF-8 页面可能乱码 - 显式指定解析器:
BeautifulSoup(html, 'lxml')比默认'html.parser'更准、更快,尤其对破损 HTML - 提取标题别只写
soup.title.string,要加if soup.title and soup.title.string判空,否则抛AttributeError - 取 meta 描述时,用
soup.find('meta', attrs={'name': 'description'}),不能只靠name='description'—— 属性名大小写敏感,且有些页面用property="og:description"
用 html.parser 自定义解析逻辑(无第三方依赖)
当你不能装包、又需要轻量可控的解析时,Python 内置的 html.parser 是底线选择,但它不建 DOM 树,只发事件:
- 必须继承
HTMLParser,重写handle_starttag、handle_data等方法,自己维护状态栈来识别嵌套层级 - 遇到自闭合标签(如
<meta>)时,handle_starttag和handle_endtag不会成对触发,得在handle_starttag里主动检查attrs判断是否含content - 它不处理实体(如
),handle_data返回的是原样字符串,需额外调用html.unescape() - 没有 CSS 选择器,想定位
<div class="article">,只能靠在 <code>handle_starttag里手动比对tag == 'div'和dict(attrs).get('class') == 'article'真正容易被忽略的是:无论用哪种方式,“解析 HTML 内容”从来不是一锤子买卖。标题可能被 JS 动态改写,meta 描述可能藏在异步加载的模板里,正文可能由 Web Component 渲染后才注入 DOM —— 你得先确认目标内容在哪个阶段存在,再选对应手段。硬套
document.querySelector或soup.find而不验证上下文,90% 的失败都发生在这里。











