爬虫---BeautifulSoup库的解析器

bs4库之所以能快速的定位我们想要的元素,是因为他能够用一种方式将html文件解析了一遍 ,不同的解析器有

不同的效果。

网络爬虫的最终目的就是过滤选取网络信息,最重要的部分可以说是解析器。


安装解析器,官方推荐使用lxml就使用它吧,效率高呀!下面是官网提供的三种安装lxml解析器的三种方式:

$ apt-get install Python-lxml

$ easy_install lxml

$ 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
>>> soup = bs4.BeautifulSoup(html_doc,'lxml')
>>> 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>	



如何具体使用呢?

bs4 库首先将传入的字符串或文件句柄转换为 Unicode的类型,这样,我们在抓取中文信息的时候,就不会有很

麻烦的编码问题了。当然,有一些生僻的编码 如:‘big5’,就需要我们手动设置编码: 

soup = BeautifulSoup(markup, from_encoding="编码方式")

对象的种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

 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.head
head_tag
# <head><title>The Dormouse's story</title></head>
# 获取head的子节点
head_tag.contents
[<title>The Dormouse's story</title>]
# 获取0号节点,并进行获取其的子节点
title_tag = head_tag.contents[0]
print(title_tag)
# <title>The Dormouse's story</title>
# 获取到0号元素的子节点,进行输出
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下的所有的文本内容呢?
如果该tag只有一个子节点(NavigableString类型):直接使用tag.string就能找到。
如果tag有很多个子、孙节点,并且每个节点里都string:
可以用迭代的方式将其全部找出:

for string in soup.strings:
    print(repr(string))
    # u"The Dormouse's story"
    # u'\n\n'
    # u"The Dormouse's story"
    # u'\n\n'
    # u'Once upon a time there were three little sisters; and their names were\n'
    # u'Elsie'
    # u',\n'
    # u'Lacie'
    # u' and\n'
    # u'Tillie'
    # u';\nand they lived at the bottom of a well.'
    # u'\n\n'
    # u'...'
    # u'\n'


目前了解到的就是这么多,更多的在实践中遇到了再了解,官方文档


原作者链接如下:

每天的学习记录都会 同步更新到: 微信公众号: findyourownway 知乎专栏:https://zhuanlan.zhihu.com/Ehco-python blog : www.ehcoblog.ml















































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值