基本概念:
简单来说,BeautifulSoup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。BeautifulSoup会帮节省数小时甚至数天的工作时间。你可能在寻找BeautifulSoup3的文档,BeautifulSoup3目前已经停止开发,官网推荐在现在的项目中使用BeautifulSoup4。
bs4的安装:
由于 Bautiful Soup 是第三方库,因此需要单独下载,下载方式非常简单,执行以下命令即可安装: pip install bs4
由于BS4 解析页面时需要依赖文档解析器,所以还需要安装 lxml 作为解析库 所以我们还需要安装lxml,安装方式如下: pip install lxml
Python 也自带了一个文档解析库 html.parser, 但是其解析速度要稍慢于 lxml。
除了上述解析器外,还可以使用 html5lib 解析器,安装方式如下: pip install html5lib
注意: bs4是依赖lxml库的,只有先安装lxml库才可以安装bs4库
文档解析器优缺点:
下表列出了主要的解析器,以及它们的优缺点:
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库执行速度适中文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快文档容错能力强 | 需要安装C语言库 |
lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"])``BeautifulSoup(markup, "xml") | 速度快唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性以浏览器的方式解析文档生成HTML5格式的文档 | 速度慢不依赖外部扩展 |
大家不需要担心C语言库的安装,基本上你的电脑可以运行都可以使用,所以你可以不需要管这个的。
推荐使用lxml作为解析器,因为效率更高。在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定。 提示: 如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的。因此我们可以更具情况去选择对应的文档解析器。具体情况具体分析。
bs4的使用
1、导入解析包:
from bs4 import BeautifulSoup
2、创建beautifulsoup解析对象
soup = BeautifulSoup(html, 'html.parser')
from bs4 import BeautifulSoup
html_doc =
"""
<html><head><title>My title</title></head>
<body>
<p class="title"><b>My p标签</b></p>
<p class="story">My name is LiHua
<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>
"""
# 创建一个soup对象
soup = BeautifulSoup(html_doc,'lxml')
print(soup,type(soup))
# 格式化文档输出
print(soup.prettify())
# 获取title标签内容 <title>The Dormouse's story</title>
print(soup.title)
# 获取title标签名称: title
print(soup.title.name)
# title标签里面的文本内容: The Dormouse's story
print(soup.title.string)
# 获取p段落
print(soup.p)
遍历文档树:
遍历子节点:
contents 返回的是一个所有子节点的列表
children 返回的是一个子节点的迭代器
descendants 返回的是一个生成器遍历子子孙孙
string 获取标签里面的内容
strings 返回是一个生成器对象用过来获取多个标签内容
stripped_strings 和strings 基本一致 但是它可以把多余的空格去掉
遍历父节点(了解)
parent 直接获得父节点
parents 获取所有的父节点
遍历兄弟节点(了解)
next_sibling 下一个兄弟结点
previous_sibling 上一个兄弟结点
next_siblings 下一个所有兄弟结点
previous_siblings上一个所有兄弟结点
案例:
from bs4 import BeautifulSoup
html_doc =
"""
<html><head><title>My title</title></head>
<body>
<p class="title"><b>My p标签</b></p>
<p class="story">My name is LiHua
<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>
"""
soup = BeautifulSoup(html_doc, "lxml")
# 获取单个标签中的内容
r1 = soup.title.string # 获取标签里面的内容
print(r1)
# 获取html中所有的标签内容
r2 = soup.html.strings # 返回是一个生成器对象用过来获取多个标签内容
print(r2)
for i in r2:
print(i)
r3 = soup.html.stripped_strings # 和strings基本一致 但是它可以把多余的空格去掉
print(r3)
for i in r3:
print(i)
搜索文档树
find():方法返回搜索到的第一条数据
find_all():方法以列表形式返回所有的搜索到的标签数据
实例应用:
html = """
<table class="tablelist" cellpadding="0" cellspacing="0">
<tbody>
<tr class="h">
<td class="l" width="374">职位名称</td>
<td>职位类别</td>
<td>人数</td>
<td>地点</td>
<td>发布时间</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=33824&keywords=python&tid=87&lid=2218">22989-金融云区块链高级研发工程师(深圳)</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-25</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=29938&keywords=python&tid=87&lid=2218">22989-金融云高级后台开发</a></td>
<td>技术类</td>
<td>2</td>
<td>深圳</td>
<td>2017-11-25</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=31236&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐运营开发工程师(深圳)</a></td>
<td>技术类</td>
<td>2</td>
<td>深圳</td>
<td>2017-11-25</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=31235&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐业务运维工程师(深圳)</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-25</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=34531&keywords=python&tid=87&lid=2218">TEG03-高级研发工程师(深圳)</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=34532&keywords=python&tid=87&lid=2218">TEG03-高级图像算法研发工程师(深圳)</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=31648&keywords=python&tid=87&lid=2218">TEG11-高级AI开发工程师(深圳)</a></td>
<td>技术类</td>
<td>4</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=32218&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=32217&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
<tr class="odd">
<td class="l square"><a id="test" class="test" target='_blank' href="position_detail.php?id=34511&keywords=python&tid=87&lid=2218">SNG11-高级业务运维工程师(深圳)</a></td>
<td>技术类</td>
<td>1</td>
<td>深圳</td>
<td>2017-11-24</td>
</tr>
</tbody>
</table>
"""
1. 获取所有的tr标签内容(以列表的形式):
# 1 获取所有的tr标签
trs = soup.find_all("tr")
for tr in trs:
print(tr)
print("*" * 150)
2. 获取所有class=even标签:
# 这里如果直接用class不行 class是作为我们的关键字,所以我们需要在class后面加一个_
trs = soup.find_all("tr", class_="even")
# trs = soup.find_all("tr", attrs={"class": "even"}) 这两种方式都可
for tr in trs:
print(tr)
print("*" * 150)
3. 获取a标签的herf值:
a_li = soup.find_all("a")
for a in a_li:
href = a.get("href")
print(href)
修改文档树
修改tag的名称和属性
修改string 属性赋值,就相当于用当前的内容替代了原来的内容
append() 像tag中添加内容,就好像Python的列表的 .append() 方法
decompose() 修改删除段落,对于一些没有必要的文章段落我们可以给他删除掉