三分钟搞定bs4库的解析器
bs4库之所以能快速的定位我们想要的元素,是因为它能够用一种方式将html文件解析了一遍 ,不同的解析器有不同的效果。
bs4解析器的选择
网络爬虫的最终目的就是过滤选取网络信息,最重要的部分可以说是解析器。解析器的优劣决定了爬虫的速度和效率。bs4库除了支持我们上文用过的‘html.parser’解析器外,还支持很多第三方的解析器,下面我们来对他们进行对比分析。
bs4库官方推荐我们使用的是lxml解析器,原因是它具有更高的效率,所以我们也将采用lxml解析器。
lxml解析器的安装:
依旧采用pip安装工具来安装:
pip install lxml
使用lxml解析器来解释网页
我们以爱丽丝文档 为例子
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>
"""
尝试一下
import bs4
#首先我们先将html文件已lxml的方式做成一锅汤
soup = bs4.BeautifulSoup(open('Beautiful Soup 爬虫/demo.html'),'lxml')
#我们把结果输出一下,是一个很清晰的树形结构。
#print(soup.prettify())
'''
OUT:
<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>
'''
如何具体的使用?
bs4 库首先将传入的字符串或文件句柄转换为 Unicode的类型,这样,我们在抓取中文信息的时候,就不会有很麻烦的编码问题了。当然,有一些生僻的编码 如:‘big5’,就需要我们手动设置编码:
soup = BeautifulSoup(markup, from_encoding="编码方式")
对象的种类:
bs4 库将复杂的html文档转化为一个复杂的树形结构,每个节点都是Python对象 ,所有对象可以分为以下四个类型:Tag , NavigableString , BeautifulSoup , Comment
我们来逐一解释:
Tag: 和html中的Tag基本没有区别,可以简单上手使用
NavigableString: 被包裹在tag内的字符串
BeautifulSoup: 表示一个文档的全部内容,大部分的时候可以吧他看做一个tag对象,支持遍历文档树和搜索文档树方法。
Comment:这是一个特殊的NavigableSting对象,在出现在html文档中时,会以特殊的格式输出,比如注释类型。
搜索文档树的最简单的方法就是搜索你想获取tag的的name:
soup.head# <head><title>The Dormouse's story</title></head>
soup.title
# <title>The Dormouse's story</title>
如果你还想更深入的获得更小的tag:例如我们想找到body下的被b标签包裹的部分
soup.body.b# <b>The Dormouse's story</b>
但是这个方法只能找到按顺序第一个出现的tag
获取所有的标签呢?
这个时候需要find_all()方法,他返回一个列表类型
tag=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>]
#假设我们要找到a标签中的第二个元素:
need = tag[1]
tag的.contents属性可以将tag的子节点以列表的方式输出:
head_tag = soup.headhead_tag
# <head><title>The Dormouse's story</title></head>
head_tag.contents
[<title>The Dormouse's story</title>]
title_tag = head_tag.contents[0]
print(title_tag)
# <title>The Dormouse's story</title>
title_tag.contents
# [u'The Dormouse's story']
另外通过tag的 .children生成器,可以对tag的子节点进行循环:
for child in title_tag.children:print(child)
# The Dormouse's story
这种方式只能遍历出子节点。如何遍历出子孙节点呢?
子孙节点:比如 head.contents 的子节点是<title>The Dormouse's story</title>,这里 title本身也有子节点:‘The Dormouse‘s story’ 。这里的‘The Dormouse‘s story’也叫作head的子孙节点
for child in head_tag.descendants:print(child)
# <title>The Dormouse's story</title>
# The Dormouse's story
如何找到tag下的所有的文本内容呢?
1、如果该tag只有一个子节点(NavigableString类型):直接使用tag.string就能找到。
2、如果tag有很多个子、孙节点,并且每个节点里都string:
我们可以用迭代的方式将其全部找出:
for string in soup.strings:print(repr(string))
# u"The Dormouse's story"
# u'
'
# u"The Dormouse's story"
# u'
'
# u'Once upon a time there were three little sisters; and their names were
'
# u'Elsie'
# u',
'
# u'Lacie'
# u' and
'
# u'Tillie'
# u';
and they lived at the bottom of a well.'
# u'
'
# u'...'
# u'
'
以上是 三分钟搞定bs4库的解析器 的全部内容, 来源链接: utcz.com/z/523314.html