最直接方式是分别用find()按name和property属性精准查找:soup.find("meta", attrs={"name": "description"})取content,soup.find("meta", attrs={"property": "og:url"})取content;注意大小写敏感、编码处理及动态渲染场景。

用 BeautifulSoup 解析 meta 标签最直接
绝大多数 SEO 元数据(如 description、keywords、og:title)都藏在 meta 标签里,BeautifulSoup 是最轻量也最可靠的提取方式。别用正则去匹配,容易漏掉属性顺序变化、换行或自闭合写法。
关键点在于:必须区分 name 和 property 两种属性——前者用于传统 SEO(如 <meta name="description" content="...">),后者用于 Open Graph(如 <meta property="og:image" content="...">)。两者不能混用 select() 一次性抓全。
- 先查
name属性:soup.find("meta", attrs={"name": "description"}),再取.get("content") - 再查
property属性:soup.find("meta", attrs={"property": "og:url"}) - 注意大小写敏感:
"OG:url"或"og:Url"都会匹配失败,标准是小写og:url - 有些页面会重复出现多个
meta[name="description"],只取第一个即可,后续多为冗余或模板注入
处理 charset 不一致导致的中文乱码
如果网页声明了 charset=gb2312 但实际用了 UTF-8 编码,或响应头没传 Content-Type,requests.get() 默认按 ISO-8859-1 解码,description 一抓就是乱码。
- 强制指定编码:
resp = requests.get(url); resp.encoding = resp.apparent_encoding or "utf-8" - 更稳妥的做法是用
resp.content+BeautifulSoup(..., from_encoding="utf-8"),绕过 requests 自动解码逻辑 - 检查
meta[charset]标签:soup.find("meta", attrs={"charset": True}),但它不一定存在,也不能替代 HTTP 响应头判断
应对动态渲染页面的 meta 标签缺失
现在很多站点用 Vue/React 渲染,初始 HTML 中 meta 标签为空或只有占位内容,真实 SEO 数据由 JS 在运行时注入。这时候用 requests + BeautifulSoup 拿不到有效值。
- 先确认是否动态:用浏览器「禁用 JS」后刷新页面,看源码里
meta[name="description"]是否还存在 - 若缺失,需改用
Playwright或Selenium启动真实浏览器上下文,等document.readyState === "complete"后再提取 - 不要盲目上 Puppeteer ——
Playwright对 Python 支持更原生,启动快、内存占用低,page.eval_on_selector("meta[name=description]", "el => el.getAttribute('content')")可精准取值
提取 meta 时忽略 robots 和 generator 等无关字段
不是所有 meta 都是 SEO 元数据。name="robots"、name="generator"、http-equiv="X-UA-Compatible" 这类标签对 SEO 分析无价值,硬塞进结果只会干扰后续 NLP 处理或入库。
- 预定义白名单更安全:
seo_names = {"description", "keywords", "author"}; seo_props = {"og:title", "og:description", "og:image", "twitter:title"} - 用
attrs={"name": lambda x: x in seo_names}或attrs={"property": lambda x: x in seo_props}过滤 - 避免用
find_all("meta")再循环判断——性能差,且容易把空 content 或重复 key 当作有效数据
真正难的不是提取,而是判断哪个 meta[property="og:image"] 是主图:可能有多个尺寸、webp/svg 混用、相对路径未补全。这类细节得结合 urljoin() 和 MIME 类型探测,不能只靠字符串匹配。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











