1.写在前面的话
今天给大家来讲讲强大牛逼的HTML解析库---Beautiful Soup,面对html的解析毫无压力,有多强?下面给大家慢慢道来!
2.Beautiful Soup是个啥?
“
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.
”当然上面是官方介绍的,在我看来其实就是帮助我们去获取一个网页上的html数据的库,他会帮我们解析出html,并且把解析后的数据返回给我们。相对于正则表达式,可能会更加的简单好用。
其实Beautiful Soup有两个版本,我们所讲的版本是4,他还有一个版本是3,为什么不讲3呢?看官方怎么说的---“Beautiful Soup 3 目前已经停止开发,我们推荐在现在的项目中使用Beautiful Soup 4, 移植到BS4”,没错,停止开发了,所以我们也没什么必要去学习3的知识。
3.Beautiful Soup的安装
如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装:
$ apt-get install Python-bs4
Beautiful Soup 4 通过PyPi发布,所以如果你无法使用系统包管理安装,那么也可以通过 easy_install 或 pip 来安装.包的名字是 beautifulsoup4 ,这个包兼容Python2和Python3.
$ easy_install beautifulsoup4
$ pip install beautifulsoup4
(在PyPi中还有一个名字是 BeautifulSoup 的包,但那可能不是你想要的,那是 Beautiful Soup3 的发布版本,因为很多项目还在使用BS3, 所以 BeautifulSoup 包依然有效.但是如果你在编写新项目,那么你应该安装的 beautifulsoup4 )
如果你没有安装 easy_install 或 pip ,那你也可以 下载BS4的源码 ,然后通过setup.py来安装.
$ Python setup.py install
如果上述安装方法都行不通,Beautiful Soup的发布协议允许你将BS4的代码打包在你的项目中,这样无须安装即可使用.
作者在Python2.7和Python3.2的版本下开发Beautiful Soup, 理论上Beautiful Soup应该在所有当前的Python版本中正常工作(摘自官方)。
安装完soup之后,我们其实还需要去安装一个解析器:
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml .根据操作系统不同,可以选择下列方法来安装lxml:
$ apt-get install Python-lxml
$ easy_install lxml
$ pip install lxml
另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib:
$ apt-get install Python-html5lib
$ easy_install html5lib
$ pip install html5lib
推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.
4.开始动手实践
安装完beautifulsoup之后,我们来快速使用一下它!
快速使用
首先我们需要导包 from bs4 import BeautifulSoup,然后我们来定义一串字符串,这串字符串里面是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">...</p>
"""
我们之后的操作都是基于上面这个字符串来的,我们使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出:
# 解析HTML,并且返回一个beautifulsoup对象
soup = BeautifulSoup(html_doc,"html.parser")
# 按照格式输出
print(soup.prettify())
打印结果:
<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 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>
接下来给大家演示几个常用的浏览结构化数据的方法:
print(soup.title)
print(soup.title.name)
print(soup.title.string)
print(soup.title.parent.name)
print(soup.p)
print(soup.p['class'])
print(soup.a)
# 返回一个数组
print(soup.find_all('a'))
print(soup.find(id="link3"))
打印出结果:
<title>The Dormouse's story</title>
title
The Dormouse's story
head
<p class="title"><b>The Dormouse's story</b></p>
['title']
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</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>]
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
2.Tag对象
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
Tag , NavigableString , BeautifulSoup , Comment .
我们先来谈谈Tag对象,Tag对象与XML或HTML原生文档中的tag相同,其实就是一个标记,举个小栗子吧:
<a href="http://example.com/elsie" class="sister" id="link1">Elsiea>
上面的a以及它里面的内容就称为Tag对象,怎么去抽取这些对象,其实上面的快速开始
中,我已经写过了,那些都是去拿到这个Tag对象。每个Tag对象都有它的名字,可以通过.name去获取。
Tag其实不仅仅能获取name,还能够修改name,举个小栗子:
# 将title改成mytitle
soup.title.name="mytitle"
print(soup.title)
print(soup.mytitle)
输出结果:
None
<mytitle>The Dormouse's story</mytitle>
再来说一说Tag里面的属性吧,看下面一段代码:
<p class="title"><b>The Dormouse's story</b></p>
这个就是我们上面html中的一段代码,我们可以看到里面有class并且值是title,Tag的属性的操作方法与字典相同。
print(soup.p['class'])
print(soup.p.get('class'))
输出结果:
['title']
['title']
其实我们也可以通过“点”来取属性,比如:.attrs,用于获取Tag中所有的属性:
print(soup.p.attrs)
输出结果:
{'class': ['title']}
2.NavigableString
有时候我们是需要获取标签中的内容,那么怎么去获取呢?这里我们就需要用到.string,给大家看下代码吧!
print(soup.p.string)
输出结果:
The Dormouse's story
BeautifulSoup用NavigableString类来包装Tag中的字符串,一个NavigableString字符和Unicode字符串相同,通过unicode()方法可以直接将NavigableString对象转换成Unicode字符串
3.搜索文档树
BeautifulSoup定义了很多的搜索方法,其中最常用的是find_all()方法,我们就拿这个来讲讲吧,其他的方法都是类似的,大家可以举一反三。
我们来看一下函数的源代码
find_all(self, name=None, attrs={}, recursive=True, text=None,
limit=None, **kwargs)
name:查找到所有名字为name的标记,字符串对象会被自动忽略掉。name参数的取值可以是字符串、正则表达式、列表、True和方法。
举个小栗子:
a = soup.find_all("a")
print(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>]
可以看到它返回的是一个列表list
kwargs参数:kwargs在python中表示的是keyword参数。如果一个指定的名字的参数不是搜索的参数名,这个时候搜索的是指定名字的Tag的属性。搜索指定名字的属性时可以使用的参数值包括字符串、正则表达式、列表、True。
举个小栗子:
a = soup.find_all(id='link2')
输出结果:
[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
还有一个小栗子也给大家看看:
a = soup.find_all(id=True)
输出结果:
[<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>]
可以看出当值为True时,它会获取到所有含有这个键的Tag对象。
再来一个小栗子:
a = soup.find_all("a", class_="sister")
print(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>]
这个应该很容易理解了,就是找到a标签下,class属性为sister的Tag对象,但是这里需要注意的是class后面需要加下划线!!!
text:通过text参数,我们可以搜索文档中的字符串内容。与name参数的可选值是相同的。
举个小栗子:
a = soup.find_all("a", text="Lacie")
print(a)
输出结果:
[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
可以看到,text参数和其他参数的完美配合!
limit:我们可以通过limit参数来限制返回的结果数量。其实效果和SQL语句中的limit效果是一样的。这里就不给大家演示了。
recursive:调用tag的find_all()方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用该参数并且将值为False。
find_all()方法就讲解到这里,其他的一些搜索方法,大家可以点击左下角的“阅读原文”进行查看!
5.END
Beautiful Soup4咱们今天就扯到这里了,我只是把一些基础和常用的方法来进行了讲解,如果需要了解更多的关于 Beautiful Soup4的用法,可以点击左下角的“阅读原文”!以上文章纯手打,如果文章中有什么错误,可以在公众号后台回复消息给我!
如果你觉得这篇文章对你有所帮助,可以点击右下角的“在看”或者给JAP君加个小鸡腿!JAVAandPython君---一个坚持原创技术文章的公众号!
关注我,你能变得更牛逼!
长按识别二维码关注