🚀 个人主页:xmp65535
🚀 专栏:python技术专栏
目录
BeautifulSoup
是一个用于从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器(例如lxml,html5lib)来解析这些文件。下面是一个基本的使用指南。
一、安装
首先,你需要安装 beautifulsoup4
包,这通常可以通过pip完成:
pip install beautifulsoup4
如果你想使用 lxml
的解析器(速度快,效率高),你还需要安装 lxml
:
pip install lxml
二、基本使用
导入BeautifulSoup类,并加载一个文档。
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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>
"""
soup = BeautifulSoup(html_doc, 'html.parser') # 或者 'lxml' 来使用lxml解析器
BeautifulSoup()
是Python库BeautifulSoup中的一个构造函数,用于解析HTML和XML文档,创建一个可以被用来提取数据的解析树(parse tree)。下面详细解释了BeautifulSoup()
函数的参数用法:
被解析的文档:
- 第一个参数是你希望BeautifulSoup帮你解析的HTML或XML文档。
- 这个参数可以是一个字符串,也可以是一个打开的文件句柄。
例如:
from bs4 import BeautifulSoup
html_doc = "<html><head><title>The Dormouse's story</title></head>"
soup = BeautifulSoup(html_doc, 'html.parser')
解析器:
- 第二个参数是用来指定解析器的字符串。BeautifulSoup可以使用多种解析器,如
html.parser
、lxml
、html5lib
。 html.parser
是Python标准库中的解析器,无需额外安装。lxml
是一个非常快的解析器,需要安装lxml
库。html5lib
解析器的容错性最好,能够按照HTML5的规范来解析文档,但速度较慢,需要安装html5lib
库。
例如:
soup = BeautifulSoup(html_doc, 'lxml')
解析器特定参数:
- 一些解析器接受额外的参数,比如
lxml
解析器允许你指定解析器应该解析HTML还是XML文档。 - 如果使用
lxml
解析XML文档,传递features='xml'
参数会触发lxml
的XML解析器。
例如:
xml_doc = "<doc><tag1>Some Data</tag1></doc>"
soup = BeautifulSoup(xml_doc, 'lxml', features='xml')
其他参数:
from_encoding
:如果文档包含非UTF-8字符编码,你可以使用这个参数来指定字符编码。如果不指定,BeautifulSoup将自动检测编码。exclude_encodings
:指定一个编码列表,告诉BeautifulSoup排除这些编码。parse_only
:一个SoupStrainer
对象,允许你只解析文档的一部分。markup
:用于直接传递内容给构造函数,而不使用第一个参数,这通常用于测试。
例如:
from bs4 import SoupStrainer
parse_only_a_tags = SoupStrainer('a')
soup = BeautifulSoup(html_doc, 'html.parser', parse_only=parse_only_a_tags)
使用 BeautifulSoup()
时,最重要的是选择一个合适的解析器。解析器的选择会影响解析的速度和效果。如果你只需要处理简单的HTML文档,html.parser
就足够了。如果你需要更高的性能或者更好的容错性,可以安装并使用 lxml
或 html5lib
。
三、导航树结构
# 访问标签内容
soup.title
# <title>The Dormouse's story</title>
soup.title.name
# 'title'
soup.title.string
# 'The Dormouse's story'
soup.title.parent.name
# 'head'
soup.p
# <p class="title"><b>The Dormouse's story</b></p>
soup.p['class']
# ['title']
soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, ...]
soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
四、搜索文档树
find_all()
和 find()
是BeautifulSoup中的两个常用方法,它们用于搜索文档树并提取信息。
基本调用格式如下:
find(name, attrs, recursive, string, **kwargs)
find_all(name, attrs, recursive, string, **kwargs)
参数说明:
name
:要查找的标签的名称或者匹配名称的任何对象。attrs
:一个 Python 字典,包含标签的属性。你可以添加一个或多个属性来精确匹配。recursive
:如果为 True(默认值),find()
方法会检查当前标签的所有子孙节点。如果为 False,则只检查当前标签的直接子节点。string
:用于查找标签的文本内容。你可以使用字符串、正则表达式、列表或者 True。**kwargs
:特定属性过滤器,例如id
、class_
等。
4.1 find_all()
find_all()
方法搜索当前标签的所有子孙节点,并返回所有符合条件的标签内容。这是一个非常灵活的方法,因为它允许你指定你想要检索的标签的名称、属性、内容,甚至是使用函数来进行复杂的匹配。
这是find_all()
的一些基本用法:
soup.find_all('tag_name') # 返回包含所有<tag_name>标签的列表
soup.find_all(['tag1', 'tag2']) # 返回包含所有<tag1>和<tag2>标签的列表
soup.find_all(id='tag_id') # 返回包含所有id属性为'tag_id'的标签的列表
soup.find_all(class_='class_name') # 返回包含所有class属性为'class_name'的标签的列表
soup.find_all(attrs={'attribute_name': 'value'}) # 返回包含所有具有指定属性的标签的列表
soup.find_all(text='text') # 返回包含文本内容为'text'的标签的列表
soup.find_all(limit=2) # 返回最多2个符合条件的标签
4.2 find()
find()
方法与find_all()
类似,但它只返回找到的第一个符合条件的标签。如果文档中存在多个匹配项,find()
将只返回第一个匹配项。这对于只需要一个元素,或者确定只有一个元素存在时特别有用。
以下是find()
的一些基本用法:
soup.find('tag_name') # 返回第一个<tag_name>标签
soup.find(id='tag_id') # 返回第一个id属性为'tag_id'的标签
soup.find(class_='class_name') # 返回第一个class属性为'class_name'的标签
soup.find(attrs={'attribute_name': 'value'}) # 返回第一个具有指定属性的标签
soup.find(text='text') # 返回第一个文本内容为'text'的标签
4.3 使用场景
通常来说,如果你只需要找到一个特定的元素,比如一个具有特定 ID 的元素,你会使用 find()
。如果你需要获取多个元素,比如文档中所有的链接,你会使用 find_all()
。
4.4 举例说明
HTML 文档:
<html>
<body>
<h1>Header 1</h1>
<h2>Header 2</h2>
<p>First Paragraph.</p>
<p>Second Paragraph.</p>
</body>
</html>
如果你使用 find_all()
:
paragraphs = soup.find_all('p')
# 返回的是包含所有 <p> 标签的列表
如果你使用 find()
:
first_paragraph = soup.find('p')
# 返回的是第一个 <p> 标签
五、标签Tag对象操作
5.1 获取和设置属性
tag['attr']
: 获取标签的某个属性值,比如tag['href']
获取<a>
标签的链接地址。tag.attrs
: 获取一个字典,包含了标签的所有属性。tag['attr'] = 'new value'
: 设置或修改标签的属性值。
5.2 访问标签的内容
tag.string
: 如果标签只有一个子节点,并且这个子节点是字符串类型,tag.string
返回子字符串。如果标签包含多个子节点,tag.string
将返回None
。tag.get_text()
: 提取标签内的所有文本内容,包括子标签内的文本。tag.text
: 类似tag.get_text()
,提取标签内的所有文本内容。
5.3 寻找标签
tag.find(name, attrs, recursive, string, **kwargs)
: 返回匹配查询的第一个标签。tag.find_all(name, attrs, recursive, string, limit, **kwargs)
: 返回一个包含所有匹配查询的标签的列表。tag.find_parent(name, attrs, string, **kwargs)
: 查找当前标签的父标签。tag.find_parents(name, attrs, string, limit, **kwargs)
: 递归查找当前标签的所有父标签。tag.find_next_sibling(name, attrs, string, **kwargs)
: 查找当前标签的下一个兄弟标签。tag.find_next_siblings(name, attrs, string, limit, **kwargs)
: 查找当前标签之后的所有兄弟标签。tag.find_previous_sibling(name, attrs, string, **kwargs)
: 查找当前标签的前一个兄弟标签。tag.find_previous_siblings(name, attrs, string, limit, **kwargs)
: 查找当前标签之前的所有兄弟标签。tag.find_next(name, attrs, string, **kwargs)
: 查找当前标签之后的第一个符合条件的标签。tag.find_all_next(name, attrs, string, limit, **kwargs)
: 查找当前标签之后的所有符合条件的标签。tag.find_previous(name, attrs, string, **kwargs)
: 查找当前标签之前的第一个符合条件的标签。tag.find_all_previous(name, attrs, string, limit, **kwargs)
: 查找当前标签之前的所有符合条件的标签。
5.4 修改标签树
tag.append(content)
: 将内容添加到标签的子节点末尾。tag.insert(position, new_child)
: 在指定位置插入新的子节点。tag.clear()
: 移除标签内的所有内容。tag.extract()
: 将标签及其内容从文档树中移除,并作为结果返回。tag.replace_with(new_tag)
: 用新标签替换当前标签。
5.5 其他方法
tag.name
: 获取或设置标签的名称。tag.copy()
: 复制当前标签。
上面这只是Tag
对象提供的一部分方法和属性。BeautifulSoup的强大功能在于它可以轻松地导航、搜索和修改HTML或XML文档。每个方法的具体用法和参数,你可以在BeautifulSoup的官方文档中找到更详细的说明。
六、css选择器使用方法
select_one()
是Beautiful Soup库中的一个方法,它允许你使用CSS选择器来选择HTML或XML文档中的第一个匹配的元素。
select()
返回的是一个列表,这个列表包含了所有匹配的元素。即使只找到一个匹配的元素,select
也会返回一个列表,而select_one
仅返回第一个匹配的元素本身。
举例:
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
#---------------------使用select()------------------------------
# 使用select查找所有class为sister的a标签
sisters = soup.select('a.sister')
print(sisters) # 输出是一个包含所有class为sister的a标签的列表
# 同样可以使用更复杂的CSS选择器
titles = soup.select('html head title')
print(titles) # 输出是一个包含title标签的列表
#---------------------使用select_one()--------------------------
# 使用select_one查找第一个class为sister的a标签
first_sister = soup.select_one('a.sister')
print(first_sister) # 输出是第一个class为sister的a标签的内容
# 可以使用任意的CSS选择器
title_tag = soup.select_one('head > title')
print(title_tag) # 输出是title标签的内容
七、解析器
BeautifulSoup使用许多不同的解析器(Python标准库中的html.parser,lxml的HTML和XML解析器,html5lib等),每个解析器都有自己的优点和缺点。例如:
BeautifulSoup(html_doc, 'html.parser') # 使用Python标准库解析
BeautifulSoup(html_doc, 'lxml') # 使用lxml库的HTML解析器,速度快
BeautifulSoup(html_doc, 'lxml-xml') # 使用lxml库的XML解析器
BeautifulSoup(html_doc, 'html5lib') # 使用html5lib库解析,最接近浏览器的方式
选择哪个解析器可能取决于个人偏好和特定任务的需求。
八、输出格式化
BeautifulSoup提供了多种格式化输出的方法,如prettify()
,它能够将解析的文档以易读的方式输出。
print(soup.prettify())
九、其他特性
BeautifulSoup还提供了许多高级功能,如CSS选择器,通过它你可以使用CSS选择器语法来查找元素:
soup.select("p:nth-of-type(3)")