about
简单来说,Beautiful Soup是python的一个库,最主要的功能是,我们通过网络请求抓取到HTML的数据,然后通过Beautiful Soup来解析HTML文档,进而帮助我们提取想要的数据。
官方解释如下:
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。 它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
安装
# pip install beautifulsoup4==4.12.2
pip install beautifulsoup4==4.12.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
Beautiful Soup在解析文档时,还需要指定解析器,除了默认的Python内置的HTML解析器之外,还支持一些第三方的解析器,这里推荐使用三方解析器lxml,该解析器更加强大,速度更快,推荐安装:
bash
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
当然了,不同的解析器虽然大致一致,但是极少的情况会出现解析结果不同的情况,这点如果你遇到这种疑惑的时候,请考虑是否使用的是同一个解释器,或者考虑更换解析器。
各种解析器的对比,来官档:https://beautifulsoup.readthedocs.io/zh_CN/latest/#id12
安装完了之后,我们就来看看怎么使用吧。
快速上手
python
# 1. 导包 虽然我们下载包下载的是beautifulsoup4,但是使用的时候,却是bs4,这点要务必牢记
from bs4 import BeautifulSoup
# 2. 被解析的HTML文档,假如我们从网络上下载了如下一段文档,我们要提取里面的超链接或者文本
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"><span>xxx</span></p>
"""
# 3. 按照如下方式实例化BeautifulSoup(待解析的文档,解析器)
soup = BeautifulSoup(html_doc, 'lxml')
# 我们会得到一个文档对象,我们通过各种方法来解析查找想要的内容
print(soup.find_all('a')) # 查找文档中的所有的超链接
"""
[
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
]
"""
for i in soup.find_all('a'):
print(i.get("href"), i.text) # 提取超链接中的href值和文本
"""
http://example.com/elsie Elsie
http://example.com/lacie Lacie
http://example.com/tillie Tillie
"""
是不是非常简单!!!
再来几个其它的姿势:
python
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"><span>xxx</span></p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
# 获取第一个匹配的title标签
print(soup.title) # <title>The Dormouse's story</title>
# 获取第一个匹配的title标签的名字
print(soup.title.name) # title
# 获取第一个匹配的title标签的文本
print(soup.title.text) # The Dormouse's story
# 获取第一个匹配的title标签的父级标签
print(soup.title.parent) # <head><title>The Dormouse's story</title></head>
# 获取第一个匹配的title标签的父级标签的名字
print(soup.title.parent.name) # head
# 获取第一个匹配的title标签的父级的文本
print(soup.title.parent.text) # The Dormouse's story
对节点和子节点解析
一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。
Beautiful Soup提供了许多操作和遍历子节点的属性。
注意: Beautiful Soup中字符串节点不支持这些属性因为字符串没有子节点。
python
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"><span>xxx</span></p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
# 拿到指定节点
body = soup.body
# print(body.contents) # 以列表的形式返回该节点的所有子节点
# 下面这么取值报错了,因为列表的0索引位置取得值不是一个标签,而是字符串,字符串没有子节点
# print(body.contents[0].contents) # AttributeError: 'NavigableString' object has no attribute 'contents'
p = body.contents[1] # 可以按照索引取值,取出子节点
# 可以对拿到的新的节点进行操作,获取想要的数据,比如获取p标签的文本
print(p) # <p class="title"><b>The Dormouse's story</b></p>
print(p.text) # The Dormouse's story
# 如果该节点有子节点的话,我们仍然可以通过contents继续以列表的形式取子节点
p = body.contents[-2] # 可以按照索引取值,取出子节点
print(p.contents) # [<span>xxx</span>]
对节点内容进行解析
对节点进行取值操作,可以通过下面几个方法来处理:
soup.text
:获取指定节点的内容,如果该节点内包含一个或多个子节点,那么它会获取所有子节点的内容。soup.string
:
python