前言完成网络请求后拿到完整网页源码只是第一步从繁杂的 HTML 文本中精准提取目标数据是爬虫核心环节之一。BeautifulSoup是 Python 生态中经典的 HTML/XML 解析库语法简洁、上手简单依托 CSS 选择器、标签层级查找、属性筛选等能力可快速定位页面元素、提取文本、链接、图片地址等内容非常适合新手入门网页解析。结合前文requests请求能力请求 解析构成静态爬虫标准工作流。本章从零讲解 BeautifulSoup 安装、对象结构、核心查询语法、实战筛选规则搭配大量可运行案例覆盖标签查找、属性提取、文本获取、节点遍历等常用场景同时总结解析易错点与优化技巧。参考文档链接BeautifulSoup 官方文档https://www.crummy.com/software/BeautifulSoup/bs4/doc/lxml 解析器说明https://lxml.de/在线 HTML 调试工具https://html-online.com/editor/一、环境安装与解析器选择1.1 库安装BeautifulSoup 不属于 Python 内置库需通过 pip 安装同时推荐搭配lxml解析器速度快、容错性强工业级首选。shell# 安装 BeautifulSoup4 pip install beautifulsoup4 # 安装 lxml 解析器必装推荐 pip install lxml备选解析器html.parserPython 内置无需额外安装兼容性好但速度偏弱。1.2 基础导入与初始化解析流程固定请求获取网页源码 → 传入 BeautifulSoup 构建解析对象 → 调用方法查询元素。 基础语法python运行from bs4 import BeautifulSoup import requests # 1. 发起请求获取网页 url https://httpbin.org/html headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36} resp requests.get(url, headersheaders, timeout5) resp.encoding utf-8 html resp.text # 2. 构建 BeautifulSoup 解析对象 # 参数1网页源码字符串参数2指定解析器 soup BeautifulSoup(html, lxml) # 格式化输出完整网页自动补全标签、排版 print(soup.prettify())关键说明prettify()格式化 HTML 代码自动换行、缩进方便查看页面结构解析器优先级lxml 内置html.parser正式项目统一使用 lxml若网页存在残缺、不规范标签lxml 会自动容错修复。二、BeautifulSoup 四大核心对象解析后页面会被拆解为四类对象理解对象类型是灵活解析的基础。2.1 Tag 标签对象HTML 中的标签div、a、p、img等对应 Tag 对象可获取标签名、属性、内部文本。python运行# 获取第一个 h1 标签 h1_tag soup.h1 # 标签名称 print(标签名, h1_tag.name) # 标签所有属性字典格式 print(标签属性, h1_tag.attrs)2.2 NavigableString 字符串对象标签内部的文本内容属于 NavigableString 对象直接取值即可拿到纯文本。python运行# 获取标签内文本 text soup.h1.string print(标签文本, text)2.3 BeautifulSoup 文档对象整个网页文档本身就是 BeautifulSoup 对象可视作根节点所有查找操作都基于该对象发起。2.4 Comment 注释对象HTML 注释内容!-- 注释 --会被识别为 Comment 对象解析时注意区分避免误提取注释文本。三、基础节点查找简易用法通过soup.标签名可快速获取页面第一个匹配标签适合结构简单、唯一标签的场景。3.1 直接通过标签名查找python运行# 获取页面第一个 a 标签 a_tag soup.a print(a标签完整内容, a_tag) # 获取a标签文本 print(a标签文本, a_tag.string) # 获取a标签 href 属性 print(链接地址, a_tag.get(href)) # 嵌套标签查找逐层定位 body soup.body p body.p print(p标签文本, p.string)3.2 属性获取两种写法标签.get(属性名)推荐写法属性不存在返回None不会报错标签[属性名]字典取值写法属性不存在直接抛异常。python运行tag soup.a print(tag.get(href)) print(tag[href])四、重点find 与 find_all 精准查找find()和find_all()是项目中使用频率最高的方法支持按标签、属性、文本多条件筛选可匹配单个 / 多个元素。4.1 find ()查找第一个匹配元素语法soup.find(nameNone, attrs{}, textNone)只返回第一个符合条件的 Tag无匹配返回None4.1.1 按标签名查找python运行# 查找第一个 p 标签 p soup.find(p) print(p.text)4.1.2 按标签 属性查找支持单属性、多属性筛选适配带 class、id 的标签。python运行# 查找 class 为 title 的 div 标签 div soup.find(div, class_title) # 注意class 是 Python 关键字语法改为 class_ # 多属性联合筛选 tag soup.find(a, attrs{href: /index.html, target: _blank})4.1.3 按文本内容查找根据标签内的文字匹配节点python运行# 查找文本包含 Hello 的标签 tag soup.find(textHello World) print(tag)4.2 find_all ()查找所有匹配元素语法同 find ()返回列表包含全部符合条件的标签无匹配返回空列表。4.2.1 基础用法批量获取同类型标签python运行# 获取页面所有 a 标签 a_list soup.find_all(a) print(f共找到 {len(a_list)} 个链接) # 遍历提取所有链接与文本 for a in a_list: link a.get(href) text a.get_text(stripTrue) # stripTrue 去除首尾空格、换行 print(f文本{text} 链接{link})4.2.2 多标签同时查找传入列表一次性匹配多种标签python运行# 同时查找所有 p 标签和 h2 标签 tags soup.find_all([p, h2]) for t in tags: print(t.text.strip())4.2.3 限制返回数量通过limit参数控制返回标签个数python运行# 只取前 2 个 a 标签 a_list soup.find_all(a, limit2) print(a_list)4.3 文本提取text /get_text ()两种方式均可提取标签内所有文本嵌套标签也会合并内容标签.string仅标签内纯文本嵌套子标签时返回 None标签.text/标签.get_text()提取当前标签 所有子标签的全部文本stripTrue自动清除换行、空格、制表符数据清洗必备。python运行tag soup.find(div) # 清除空白字符后提取文本 content tag.get_text(stripTrue) print(content)五、CSS 选择器 select推荐主流用法select()方法依托 CSS 选择器语法定位元素语法直观、和前端通用复杂页面优先使用 select是目前行业主流解析方案。语法soup.select(CSS选择器)永远返回列表匹配不到则返回空列表5.1 常用选择器规则与实战5.1.1 标签选择器直接写标签名匹配所有对应标签python运行# 选择所有 p 标签 res soup.select(p) for item in res: print(item.text.strip())5.1.2 class 类选择器语法.类名python运行# 选择 classnews 的所有标签 news_list soup.select(.news)5.1.3 id 选择器语法#id名python运行# 选择 idmain 的标签 main_tag soup.select(#main) print(main_tag[0].text.strip())5.1.4 属性选择器语法标签[属性值]精准匹配带指定属性的标签常用于提取链接、图片python运行# 选择所有 href 属性为指定值的 a 标签 a_tags soup.select(a[href/about]) # 提取所有图片地址 img_tags soup.select(img) for img in img_tags: img_url img.get(src) print(图片链接, img_url)5.1.5 层级选择器父子 / 后代空格分隔后代选择器所有下级节点分隔直接子节点仅一级子标签python运行# 查找 div 内部所有 a 标签后代 res soup.select(div a) # 查找 div 直接子级 a 标签 res soup.select(div a)5.2 select_one ()匹配单个元素等价于select()[0]专门用于只取第一个匹配项避免列表取值python运行# 获取第一个 classtitle 的标签 title soup.select_one(.title) print(title.text.strip())六、节点遍历兄弟 / 父子节点部分页面结构无唯一 class/id需通过节点关系遍历查找适用于规整列表结构。6.1 子节点与父节点python运行tag soup.select_one(.list) # 所有直接子节点 children tag.children for child in children: if child.name: # 过滤空行、文本节点 print(child) # 获取父节点 parent tag.parent print(parent.name)6.2 兄弟节点同级标签python运行# 下一个兄弟节点 next_sib tag.next_sibling # 上一个兄弟节点 prev_sib tag.previous_sibling # 所有后面的兄弟节点 all_next tag.next_siblings七、综合实战 1列表页数据提取模拟资讯列表页完成请求 → 解析 → 批量提取标题、链接、简介全流程整合前面所有知识点。python运行import requests from bs4 import BeautifulSoup # 基础配置 url https://httpbin.org/html headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36 } # 1. 发起请求 resp requests.get(url, headersheaders, timeout6) resp.encoding utf-8 # 2. 构建解析对象 soup BeautifulSoup(resp.text, lxml) # 3. CSS选择器批量提取列表数据 news_items soup.select(body p) print( 列表数据提取结果 ) for idx, item in enumerate(news_items, 1): text item.get_text(stripTrue) print(f第{idx}条{text})八、综合实战 2图片链接批量抓取实战场景爬取页面所有图片地址是爬虫高频需求。python运行import requests from bs4 import BeautifulSoup url https://httpbin.org/images headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0.0.0 Safari/537.36} resp requests.get(url, headersheaders, timeout8) soup BeautifulSoup(resp.text, lxml) # 选中所有 img 标签 img_list soup.select(img) print(页面所有图片链接) for img in img_list: src img.get(src) if src: # 拼接完整绝对链接相对地址补全域名 full_url url.rstrip(/) / src.lstrip(/) print(full_url)九、常见问题与避坑指南9.1 找不到目标标签检查页面是否为JS 动态渲染BeautifulSoup 只能解析静态 HTML动态内容无法获取后续需使用 Selenium/Playwright核对选择器语法class、id、标签名大小写严格区分查看源码浏览器开发者工具 Elements 面板为准不要只看预览界面。9.2 文本出现大量换行、空格解决方案提取文本时统一使用get_text(stripTrue)清除空白字符。9.3 class 筛选失效HTML 中 class 存在多个值时完整匹配或模糊匹配html预览div classbox item/divpython运行# 匹配包含 box 的标签 soup.select(.box)9.4 相对链接无法访问页面中src/1.jpg、href/index属于相对路径必须手动拼接主域名转为绝对链接。