beautiful soup库的使用笔记
下面是可以直接复制到博客园的润色版 Markdown。发布前请注意:原文中的图片路径是本机临时路径,博客园无法直接显示,需要重新上传图片后替换图片地址。
Beautiful Soup 库使用笔记
简介
Beautiful Soup 是一个常用的 Python 网页解析库。它不要求编写复杂的正则表达式,只需几个简单语句,就可以从 HTML 或 XML 文档中提取指定元素和文本,适合入门爬虫和数据提取。
准备工作
安装 beautifulsoup4 和解析器 lxml:
pip install beautifulsoup4
pip install lxml
也可以合并安装:
pip install beautifulsoup4 lxml
快速开始
html = """
<html>
<head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "lxml")
print(soup.prettify())
print(soup.title.string)
输出示例:
<html>
<head>
<title>
The Dormouse's story
</title>
</head>
<body>
<p class="title" name="dromouse">
<b>
The Dormouse's story
</b>
</p>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">
<!-- Elsie -->
</a>
,
<a class="sister" href="http://example.com/lacie" id="link2">
Lacie
</a>
and
<a class="sister" href="http://example.com/tillie" id="link3">
Tillie
</a>
;
and they lived at the bottom of a well.
</p>
<p class="story">
...
</p>
</body>
</html>
The Dormouse's story
prettify() 方法可以将解析后的 HTML 以标准缩进格式输出,便于查看结构。
获取节点
使用“对象.节点名称”即可获取节点。例如:
print(soup.title)
print(soup.p)
print(soup.a)
需要注意的是,这种写法默认返回第一个匹配到的节点。
获取名称
在节点后添加 name 属性即可获取节点名称:
print(soup.title.name)
输出:
title
获取属性
可以调用 attrs 获取节点的所有属性:
print(soup.p.attrs)
print(soup.p.attrs["name"])
运行结果:
{'class': ['title'], 'name': 'dromouse'}
dromouse
也可以使用更简洁的写法:
print(soup.p["name"])
print(soup.p["class"])
输出:
dromouse
['title']
注意:class 属性通常返回列表,因为一个标签可以有多个 class。
嵌套选择
Tag 类型对象可以继续向下选择子节点:
print(soup.p.b)
print(soup.p.b.string)
输出:
<b>The Dormouse's story</b>
The Dormouse's story
关联选择
子节点
contents属性:将直接子节点以列表方式返回。children属性:将直接子节点以生成器方式返回。descendants属性:将所有子孙节点以生成器方式返回。
父节点
parent属性:获取父节点。parents属性:获取所有祖先节点,返回生成器。
兄弟节点
next_sibling和previous_sibling:返回下一个、上一个兄弟节点。next_siblings和previous_siblings:返回后面、前面全部兄弟节点。
实际使用时要注意,兄弟节点可能是换行符或空白文本对应的 NavigableString,不一定是 Tag 对象。
提取信息
常见提取方式如下:
print(soup.title.string) # 获取文本
print(soup.a["href"]) # 获取属性
print(soup.p.get_text()) # 获取节点内全部文本
常用属性包括:
name:节点名称。attrs:节点属性字典。string:节点内文本。text/get_text():获取节点内全部文本。
原文此处为截图,发布到博客园时请重新上传图片:


方法选择器
find_all(name, attrs, recursive, text, **kwargs) 可以查询所有符合条件的元素,返回列表。
常用参数说明:
name:按标签名查找。attrs:按属性字典查找。recursive:是否递归查找子孙节点,默认是True。text/string:按文本内容查找,具体参数名在不同版本中略有差异。**kwargs:按常用属性查找,例如class_。
示例:
print(soup.find_all("p"))
print(soup.find_all("p", class_="story"))
print(soup.find_all(attrs={"name": "dromouse"}))
find() 与 find_all() 类似,但只返回第一个匹配结果;find_all() 返回列表。
CSS 选择器
使用 select() 方法可以通过 CSS 选择器查找节点:
html = '''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "lxml")
print(soup.select(".panel .panel-heading"))
print(soup.select("ul li"))
print(soup.select("#list-2 .element"))
print(type(soup.select("ul")[0]))
运行结果:
[<div class="panel-heading">
<h4>Hello</h4>
</div>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
<class 'bs4.element.Tag'>
select() 返回的是列表,即使只匹配到一个元素,也需要通过索引取出,例如 soup.select("ul")[0]。
同样可以继续嵌套选择、获取属性和获取文本:
for li in soup.select("#list-2 .element"):
print(li.get_text())
print(soup.select("ul")[0]["id"])
常见报错
如果出现如下报错:
Traceback (most recent call last):
File "D:\PythonProject\python20.py", line 13, in <module>
soup = BeautifulSoup(html, 'lxml')
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\PythonProject\.venv\Lib\site-packages\bs4\__init__.py", line 366, in __init__
raise FeatureNotFound(
bs4.exceptions.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
说明 Beautiful Soup 没有找到可用的 lxml 解析器。常见原因包括:
- 当前 Python 环境没有安装
lxml。 - PyCharm 使用的解释器与安装依赖的环境不一致。
lxml与当前 Python 版本不兼容。- 虚拟环境损坏或依赖安装不完整。
可以按以下步骤排查:
- 确认当前解释器版本和路径。PyCharm 可以查看右下角解释器,命令行可以执行:
python -c "import sys; print(sys.executable)"
- 在当前解释器环境中重新安装依赖:
python -m pip install beautifulsoup4 lxml
- 升级 pip 和相关库:
python -m pip install --upgrade pip beautifulsoup4 lxml
- 如果只是临时测试,也可以改用 Python 内置解析器:
soup = BeautifulSoup(html, "html.parser")
- 如果当前 Python 版本过高,或者
lxml安装、加载异常,可以尝试使用 Python 3.12 重建虚拟环境,然后重新安装beautifulsoup4和lxml。
在 PyCharm 中,可以打开项目解释器设置,选择 Python 3.12 对应的解释器,应用后重新安装依赖。路径通常为:
Settings → Project → Python Interpreter
或者直接点击 PyCharm 右下角的解释器状态进行切换。
浙公网安备 33010602011771号