一、简介
Beautiful Soup 4 库和 lxml 库一样,是python的一个HTML或XML的解析库,我们可以用它来方便的从网页中提取数据,它拥有强大的API和多样的解析方式。
与 lxml 对比:lxml 只会局部遍历,而Beautiful Soup 是基于 HTML DOM 的,它会载入整个文档,解析DOM树,因此时间和内存开销都会很大,所以性能低于 lxml。
1、安装Beautiful Soup 4 库
1、dos命令窗口输入:pip install bs4
2、pycharm 中搜索安装
中文文档:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/
2、三大解析工具对比
| 解析工具 | 解析速度 | 使用难度 |
|---|---|---|
| Beautiful Soup | 慢 | 简单 |
| lxml | 中等 | 中等 |
| 正则 | 快 | 困难 |
二、简单使用
from bs4 import BeautifulSoup
html ='''
<html>
<body>
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="www.baidu.com"><span class="bold">third item</span></a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</body>
</html>
'''
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
运行结果:
<html>
<body>
<div>
<ul>
<li class="item-0">
<a href="link1.html">
first item
</a>
</li>
<li class="item-1">
<a href="link2.html">
second item
</a>
</li>
<li class="item-inactive">
<a href="www.baidu.com">
<span class="bold">
third item
</span>
</a>
</li>
<li class="item-1">
<a href="link4.html">
fourth item
</a>
</li>
<li class="item-0">
<a href="link5.html">
fifth item
</a>
</li>
</ul>
</div>
</body>
</html>
解释:
1、soup.prettify():按照 HTML 语言的嵌套格式输出 html 代码。
2、Beautiful Soup 可以调用的解析器的特点:

三、常见的四种对象
1、Tag
Tag对象与XML或HTML原生文档中的tag相同,Beautiful Soup 中所有的标签都是 Tag 类型,并且 Beautiful Soup 的对象其本质上也是一种 Tag 类型。所以其实一些方法,比如 find、find_all并不是 Beautiful Soup 的,而是 Tag 的。
from bs4 import BeautifulSoup
html ='''
<html>
<body>
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="www.baidu.com"><span class="bold">third item</span></a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
<b><!--这是一个注释--></b>
</div>
</body>
</html>
'''
soup = BeautifulSoup(html, 'lxml')
print(type(soup.li), soup.li)
print(soup.li.name)
print(soup.li.attrs)
print(soup.li['class'])
print(soup.li.get('class'))
soup.li['class'] = 'new attr'
print(soup.li)
运行结果:
<class 'bs4.element.Tag'> <li class="item-0"><a href="link1.html">first item</a></li>
li
{'class': ['item-0']}
['item-0']
['item-0']
<li class="new attr"><a href="link1.html">first item</a></li>
解释:
1、soup.li:获取 html 文本中的第一个 li 标签的内容,它是 <class ‘bs4.element.Tag’> 类型。
2、soup.li.name:获取 li 标签的标签名。
3、soup.li.attrs:获取 html 文本中的第一个 li 标签的属性,返回字典类型。
4、soup.li[‘class’],soup.li.get(‘class’):获取 html 文本中的第一个 li 标签的 class 属性值,返回列表类型。
5、soup.li[‘class’] = ‘new attr’ :把 html 文本中的第一个 li 标签的 class 属性值改为 new attr。
2、NavigableString
如果拿到标签后,还想获取标签中的文本内容,那么可以通过 Tag.string 的方式获取。
...ship...
soup = BeautifulSoup(html, 'lxml')
print(type(soup.li.string), soup.li.string)
#运行结果:
#<class 'bs4.element.NavigableString'> first item
查看 NavigableString 类:

结论:说明 NavigableString 继承于 python 的 str ,所以 str 的方法和属性它都能使用,如下:
st_li = soup.li.string
res = st_li.split(' ')
print(res) #['first', 'item']
3、BeautifulSoup
BeautifulSoup 对象表示一个文档的全部内容,大部分时候,我们可以把它当做 Tag 对象,它支持遍历文档树和搜索文档树中描述的大部分的方法。
...ship...
print(type(soup)) #<class 'bs4.BeautifulSoup'>
查看 BeautifulSoup 类:

结论:说明 BeautifulSoup 继承于 Tag 类,所以 Tag 的方法和属性它都能使用。
4、Comment
前三种对象基本已经覆盖了 HTML 和 XML 中的所有内容,但是还有一种特殊的对象无法处理,如 HTML 的注释部分。
...ship...
print(type(soup.b.string), soup.b.string)
# <class 'bs4.element.Comment'> 这是一个注释
查看 Comment 类:


结论:说明 Comment 继承于 PreformattedString 类,而 PreformattedString 又继承于 NavigableString 类,所以 NavigableString 的方法和属性它都能使用。
四、遍历及搜索文档树
1、contents 和 children
from bs4 import BeautifulSoup
html ='''
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title">The Dormouse's story</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>
<b><!--这是一个注释--></b>
<p class="story">...</p>
'''
soup = BeautifulSoup(html, 'lxml')
head_tag = soup.head
print(type(head_tag.contents), head_tag.contents) #<class 'list'> [<title>The Dormouse's story</title>]
print(type(head_tag.children), head_tag.children) #<class 'list_iterator'> <list_iterator object at 0x0000028934A9CA90>
for ite in head_tag.children:
print(type(ite), ite) # <class 'bs4.element.Tag'> <title>The Dormouse's story</title>
解释:
1、head_tag.contents:获取 title 标签的内容,返回列表类型。
2、head_tag.children:获取 title 标签的内容,返回迭代器类型。
2、string、strings 和 stripped_strings
...ship...
s1 = soup.p.string
print(type(s1), s1) # <class 'bs4.element.NavigableString'> The Dormouse's story
s2 = soup.strings
print(type(s2), s2) # <class 'generator'> <generator object Tag._all_strings at 0x000001C57E767570>
for string in soup.strings:
print(string)
s3 = soup.stripped_strings
print(type(s3), s3) # <class 'generator'> <generator object Tag.stripped_strings at 0x0000020C3B687D68>
for string in soup.stripped_strings:
print(string)
解释:
1、soup.p.string:获取第一个 p 标签下的文本,返回字符串类型,如果这个标签下有多行文本,那么将无法获取。
2、soup.strings:获取整个 HTML 文档中的所有文本,不会去掉空白字符,返回生成器类型。
3、soup.stripped_strings:获取整个 HTML 文档中的所有文本,并且会去掉空白字符,返回生成器类型。
3、find 和 find_all
1、find : 找到第一个满足条件的标签后,返回一个元素。
2、find_all :找到所有满足条件的标签后,返回一个列表。
from bs4 import BeautifulSoup
html ='''
<html>
<body>
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="www.baidu.com"><span class="bold">third item</span></a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
<b><!--这是一个注释--></b>
</div>
</body>
</html>
'''
soup = BeautifulSoup(html, 'lxml')
# 获取所有的li标签
lis = soup.find_all('li')
# 获取第二个li标签
li_02 = soup.find_all('li', limit=2)[1]
# 获取class等于item-1的li标签
lis_item1 = soup.find_all('li', class_='item-1') #方式一
lis_item2 = soup.find_all('li', attrs={'class':'item-1'}) #方式二
# 获取所有a标签的href属性值
list_a = soup.find_all('a')
for a in list_a:
href = a['href'] #也可以写成 href = a.attrs['href']
print(href)
# 获取所有的文本到一个列表中
list_ul = soup.find_all('ul')
for ul in list_ul:
infos = list(ul.stripped_strings)
print(infos)
4、select 方法(CSS语法)
from bs4 import BeautifulSoup
html ='''
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title">The Dormouse's story</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>
<b><!--这是一个注释--></b>
<p class="story">...</p>
'''
soup = BeautifulSoup(html, 'lxml')
# 通过标签名查找
print(soup.select('a'))
# 通过类名查找
res = soup.select('.story')
print(len(res), res)
# 通过 id 查找
print(soup.select('#link1'))
# 组合查找
print(soup.select('head title'))
# 属性查找
print(soup.select('a[href="http://example.com/elsie"]'))
# 获取文本内容
print(soup.select('title')[0].get_text())
本文介绍了Python的Beautiful Soup 4库,用于HTML和XML文档解析。内容包括库的安装、与lxml的对比、基本使用、四种常见对象(Tag、NavigableString、BeautifulSoup、Comment)的特性和遍历搜索文档树的方法。Beautiful Soup通过DOM解析方式提供方便的数据提取,但性能上可能不如lxml。示例中展示了如何操作Tag对象,以及使用find、find_all和select方法进行查询。

56万+

被折叠的 条评论
为什么被折叠?



