查看原文
其他

Python之BeautifulSoup模块:解析文档树的利器(二)

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:张   邯

编辑作者:胡   婧

技术总编:张学人

爬虫俱乐部是您身边的科研助手,能够为您在数据处理实证研究中提供帮助。承蒙30000+粉丝的支持与厚爱,我们在腾讯课堂推出了网络视频课程,专注于数据整理、网络爬虫、循环命令编制和结果输出…李老师及团队精彩地讲解,深入浅出,注重案例与实战,让您更加快速高效地掌握Stata技巧及数据处理的精髓,而且可以无限次重复观看,百分百好评,简单易学,一个月让您从入门到精通。绝对物超所值!观看学习网址:https://ke.qq.com/course/286526?tuin=1b60b462,敬请关注!

有问题,不要怕!点击推文底部“阅读原文”下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~

之前我们已经介绍了关于BeautifulSoup模块的入门使用方法,大家在体验了它的便利之后多少会有些迷惑,觉得似懂非懂,本篇文章我们介绍一下BeautifulSoup对象的基本分类和模块中浏览结构化数据的几个方法,进一步加深对这个库的理解,提高处理结构化数据的能力。为了方便介绍本篇文章提到的方法,我们使用如下示例HTML文档

<html> <head> </head> <body>  <b>   <!--Hey, buddy. Want to buy a used parser?-->  </b>  <title>   The Dormouse's story
 </title>  <p class="title frist only" id="my id">   <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="link2">    Tillie
  </a>   ; and they lived at the bottom of a well.
 </p>  <p class="story">   ...
 </p> </body>
</html>

通过上篇文章的介绍,我们已经有一个基本认识:BeautifulSoup是将一个复杂的HTML文档转化成一个复杂的树形结构,每个节点都是一个Python对象,可以用type( )来查看它们的类型。这些对象一共分为如下四种:

01

tag

与原生文档中的tag相同,是一种标签对象,它可以有很多方法和属性,上篇文章我们介绍了.find、.parent等方法,并且提到了'class'、'id'等属性,用它们进行了一个简单的数据定位和清洗,此处我们将进一步系统介绍几个常用的属性方法

name

每个标签都有自己的名字,可以通过.name来获取,这样返回一个str,可以用于其他操作。

例如,我们想获取所有id为'link2'的标签名,可以键入以下命令:

for tag in soup.find_all(id='link2'):    print(tag.name)

得到如下结果,结果表明,一共有两个标签的id符合要求,并且标签名是a和a,观察文档,我们可以得到相同的结论。

 attributes

BS对象会把每个标签的各个属性生成一个字典(dictionary),操作方法(添加、删除、修改)与字典是相同的。

<1>获取所有的属性:soup.tag.attrs

此处tag为标签名,可以替换成任一标签名,来获取它的属性。我们尝试获取第一个'a'标签的属性,键入:

soup.a.attrs

得到如下结果,说明此标签一共有三个属性:'class''href''id',其值也都给出。

<2>“点”取属性:soup.tag['attrs']

①标签属性作为字典,每个键值可以通过soup.tag['attrs']查看。其中soup.tag是一个标签,他可以包含很多级。

我们可以用.find方法来找到第一个 ‘class’的值为sister的标签:

tag = soup.find('a',class_ = 'sister')

结果如下:

然后查看这个标签的'href'属性,可以观察到,它是一个URL,并且只有这一个值。键入命令:

tag['href']

返回结果为:

通过观察源文档,我们也可以得到相同的结果。

②当对象有多值属性时,返回list,HTML文档中最常见的多值属性是'class'。这些多值属性是定义在HTML语法规则里的,也就是固定的。如果某个属性没有规定可以多值,但看起来好像有多个值,那么Beautiful Soup 会将这个属性作为字符串返回。

我们分别查看第一个'p'标签的'class'属性和'id'属性,可以看到,'class'属性共有三个值,分别为title、first和only。而'id'属性虽然看起来是两个值my和id,但是这个属性在任何版本的HTML定义中都没有多值,所以此时,将会作为字符串整体返回。键入命令:

soup.p['class'] soup.p['id']

返回结果如下:

02

Navigable String

上篇文章已经介绍过,这个对象通常是我们关注的要爬取的信息,可以通过.string来获取。

03

BeautifulSoup

BS(BeautifulSoup)对象表示一个HTML文档的全部内容,大部分时候,我们可以把它当成一个tag对象,支持大部分方法,在上篇文章中.parents方法获取所有祖宗节点时,我们曾经碰到过它,它是所有节点的最后一级父节点。

但它也有一些特殊性,比如它没有'name'和'attributes'属性,但BeautifulSoup也设定查看它的name时将返回一个值为"[document]"的特殊属性,也就是输入:

soup.name

会返回:

04

comment

上述三个对象几乎涵盖了所有HTML文档的内容,但熟悉HTML文档的人都知道,为了增加可读性会做一些注释(即在<!-- -->中的内容,如下图所示),这些内容的存在不是为了解析,而是为了给读它的人看,所以不具有结构化的特性,它们会被放在comment对象中。

一般意义来说,它是一个特殊的Navigable String对象,所以我们同样以.string来获取,由于本文使用的HTML文档注释在第一个’b’标签中,我们直接使用soup.b.string,如果有多处注释则需要其他获取方法,其定位方法与上篇文章的方法相同,同时查看一下它的类型

comment = soup.b.string type(comment)

可以看到,它的类型是bs4.element.Coment,而并非一个Navigable String对象。我们也可以获取一下它的值:

怎么样?看完了本篇文章有没有觉得思路清晰了些呢?对BeautifulSoup的理解也更深刻了些吧?掌握好这些基础知识后,就可以学习一些高阶技能了!在接下来的文章中,我们将介绍BeautifulSoup的更复杂的用法,尽请期待!

对爬虫俱乐部的推文累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!

往期推文推荐:

关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。

3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存