爬虫利器 Beautiful Soup 之遍历文档

Beautiful Soup 简介

Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,它提供了一些简单的操作方式来帮助你处理文档导航,查找,修改文档等繁琐的工作。因为使用简单,所以 Beautiful Soup 会帮你节省不少的工作时间。

Beautiful Soup 安装

你可以使用如下命令安装 Beautiful Soup。二选一即可。

$ easy_install beautifulsoup4$ pip install beautifulsoup4

Beautiful Soup 不仅支持 Python 标准库中的 HTML 解析器,还支持很多第三方的解析器,比如 lxml,html5lib 等。初始化 Beautiful Soup 对象时如果不指定解析器,那么 Beautiful Soup 将会选择最合适的解析器(前提是你的机器安装了该解析器)来解析文档,当然你也可以手动指定解析器。这里推荐大家使用 lxml 解析器,功能强大,方便快捷,而且该解析器是唯一支持 XML 的解析器。

你可以使用如下命令来安装 lxml 解析器。二选一即可。

$ easy_install lxml$ pip install lxml

Beautiful Soup 小试牛刀

Beautiful Soup 使用来起来非常简单,你只需要传入一个文件操作符或者一段文本即可得到一个构建完成的文档对象,有了该对象之后,就可以对该文档做一些我们想做的操作了。而传入的文本大都是通过爬虫爬取过来的,所以 Beautiful Soup 和 requests 库结合使用体验更佳。

# demo 1from bs4 import BeautifulSoup# soup = BeautifulSoup(open(“index.html”))soup = BeautifulSoup(“indexcontent”, “lxml”) # 指定解析器print(soup.head)# 输出结果index

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

Tag 就是 HTML 的一个标签,比如 p,p 标签等,也是我们用的最多的一个对象。

NavigableString 指标签内部的文字,直译就是可遍历的字符串。

BeautifulSoup 指一个文档的全部内容,可以当成一个 Tag 来处理。

Comment 是一个特殊的 NavigableString,其输出内容不包括注视内容。

为了故事的顺利发展,我们先定义一串 HTML 文本,下文的所有例子都是基于这段文本的。

html_doc = “””index

首页

我常用的网站GoogleBaiduBing

“””

子节点

Tag 有两个很重要的属性,name 和 attributes。期中 name 就是标签的名字,attributes 是标签属性。标签的名字和属性是可以被修改的,注意,这种修改会直接改变 BeautifulSoup 对象。

# demo 2soup = BeautifulSoup(html_doc, “lxml”);p_tag = soup.pprint(p_tag.name)print(p_tag[“class”])print(p_tag.attrs)p_tag.name=”myTag” # attrs 同样可被修改,操作同字典print(p_tag)#输出结果p[‘title’]{‘class’: [‘title’]}首页

由以上例子我么可以看出,可以直接通过点属性的方法来获取 Tag,但是这种方法只能获取第一个标签。同时我们可以多次调用点属性这个方法,来获取更深层次的标签。

# demo 3soup = BeautifulSoup(html_doc, “lxml”);print(soup.p.b)#输出结果首页

如果想获得所有的某个名字的标签,则可以使用 find_all(tag_name) 函数

# demo 4soup = BeautifulSoup(html_doc, “lxml”);a_tags=soup.find_all(“a”)print(a_tags)#输出结果[Google, Baidu, Bing]

我们可以使用 .contents 将 tag 以列表方式输出,即将 tag 的子节点格式化为列表,这很有用,意味着可以通过下标进行访问指定节点。同时我们还可以通过 .children 生成器对节点的子节点进行遍历。

# demo 5soup = BeautifulSoup(html_doc, “lxml”);head_tag=soup.headprint(head_tag)print(head_tag.contents)for child in head_tag.children:print(“child is : “, child)#输出结果index[index]child is : index

.children 只可以获取 tag 的直接节点,而获取不到子孙节点,.descendants 可以满足你。

# demo 6soup = BeautifulSoup(html_doc, “lxml”);head_tag=soup.headfor child in head_tag.descendants:print(“child is : “, child)# 输出结果child is : indexchild is : index

父节点

通过 .parent 属性获取标签的父亲节点。 title 的父标签是 head,html 的父标签是 BeautifulSoup 对象,而 BeautifulSoup 对象的父标签是 None。

# demo 7soup = BeautifulSoup(html_doc, “lxml”);title_tag=soup.titleprint(title_tag.parent)print(type(soup.html.parent))print(soup.parent)# 输出结果indexNone

同时,我们可以通过 parents 得到指定标签的所有父亲标签。

# demo 8soup = BeautifulSoup(html_doc, “lxml”);a_tag=soup.afor parent in a_tag.parents: print(parent.name)# 输出结果pbodyhtml[document]

兄弟节点

通过 .next_sibling 和 .previous_sibling 来获取下一个标签和上一个标签。

# demo 9soup = BeautifulSoup(html_doc, “lxml”);p_tag=soup.pprint(p_tag.next_sibling)print(p_tag.next_sibling.next_sibling)# 输出结果

你可能会纳闷,调用了两次 next_sibling 怎么只有一个输出呢,这方法是不是有 bug 啊。事实上是 p 的第一个 next_sibling 是p 和 p 之间的换行符。这个规则对于 previous_sibling 同样适用。

另外,我们可以通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出。在该例子中,我们在每次输出前加了前缀,这样就可以更直观的看到 dib 的第一个 previous_sibling 是换行符了。

# demo 10soup = BeautifulSoup(html_doc, “lxml”);p_tag=soup.pfor pre_tag in p_tag.previous_siblings:print(“pre_tag is : “, pre_tag)# 输出结果pre_tag is : pre_tag is :

我常用的网站GoogleBaiduBing

pre_tag is : pre_tag is :

首页

pre_tag is :

前进和后退

通过 .next_element 和 .previous_element 获取指定标签的前一个或者后一个被解析的对象,注意这个和兄弟节点是有所不同的,兄弟节点是指有相同父亲节点的子节点,而这个前一个或者后一个是按照文档的解析顺序来计算的。

比如在我们的文本 html_doc 中,head 的兄弟节点是 body(不考虑换行符),因为他们具有共同的父节点 html,但是 head 的下一个节点是 title。即soup.head.next_sibling=title soup.head.next_element=title

# demo 11soup = BeautifulSoup(html_doc, “lxml”);head_tag=soup.headprint(head_tag.next_element)title_tag=soup.titleprint(title_tag.next_element)# 输出结果indexindex

同时这里还需要注意的是 title 下一个解析的标签不是 body,而是 title 标签内的内容,因为 html 的解析顺序是打开 title 标签,然后解析内容,最后关闭 title 标签。

另外,我们同样可以通过 .next_elements 和 .previous_elements 来迭代文档树。由遗下例子我们可以看出,换行符同样会占用解析顺序,与迭代兄弟节点效果一致。

# demo 12soup = BeautifulSoup(html_doc, “lxml”);p_tag=soup.pfor next_element in p_tag.next_elements:print(“next_element is : “, next_element)# 输出结果next_element is : 这是注释内容next_element is : next_element is :

next_element is : …next_element is : next_element is :

next_element is : …next_element is : next_element is :

Beautiful Soup 总结

本章节介绍了 Beautiful Soup 的使用场景以及操作文档树节点的基本操作,看似很多东西其实是有规律可循的,比如函数的命名,兄弟节点或者下一个节点的迭代函数都是获取单个节点函数的复数形式。

同时由于 HTML 或者 XML 这种循环嵌套的复杂文档结构,致使操作起来甚是麻烦,掌握了本文对节点的基本操作,将有助于提高你写爬虫程序的效率。

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年7月7日
下一篇 2022年7月7日

相关推荐

  • 平均数怎么算公式excel(如何计算多个数的平均数)

    在用 Excel 处理数据时,经常会遇到需要计算平均值的情况。 学校里各科成绩出来了,要统计平均分; 不同的领导打分占比不一样,要计算加权总得分; 单位内部年终评比相互打分,要去掉…

    2022年4月19日
  • 惊艳!Alibaba最新「10亿级并发系统设计文档」GitHub狂揽8000星

    前言 每逢阿里开展大型活动,比如、双11、双12、等等,使用淘宝的用户就会瞬间飙升,为何淘宝APP从来没有崩盘?淘宝的亿级并发系统架构又是如何设计的呢?又是如何承受住亿级流量带来的…

    2022年6月19日
  • 打造核心竞争力 辛选创始人辛巴构建多维度品控体系

    近年来,直播电商火热依旧,但用户的关注点已经从主播转移到产品本身,这使得直播电商企业愈发重视产品品质,各家企业纷纷投入升级品质管理体系的队伍之中。在一众直播电商企业中,辛选集团创始…

    2022年8月4日
  • iPhone也能装华为鸿蒙?分享一波骚操作

    机哥想起,大概是四五年前,安卓手机玩家流行过一阵子,利用各种主题、启动器、插件,来模拟出iOS系统的味道。 谁能想到,现在风水轮流转,轮到iPhone玩家想把手机搞成安卓了。 尤其…

    2022年6月22日
  • 秦始皇的心腹为何全是“蒙”姓?本不是秦人,三代人铸就秦国忠魂

    秦国经过商鞅变法后,在提拔武将方面不再注重出身而是战功,所以想要在秦国建立一个武将世家并非易事,其中王翦所在的王家,蒙恬、蒙毅所在的蒙家算是秦国较为著名的两个武将世家。 与王家出身…

    2022年9月19日
  • 这个有着“亚洲水陆之著”的天然溶洞,是江西一处理想的避暑之地

    一说起溶洞,大家可能会想到云贵川地区,但是不可忽略的是:江西也是一个分布了大大小小许多溶洞的宝藏之地。 说起江西的溶洞,确实不少。比如,萍乡的孽龙洞、宜春酌江白龙洞、彭泽龙宫洞、万…

    2022年8月9日
  • 怎么查看自己电脑是什么操作系统

    电脑系统分为32位和64位,安装软件的时候会涉及系统,因此大家安装之前查看一下电脑的操作系统,避免下载软件不支持当前系统,怎么查看电脑系统呢?请参考以下操作: 怎么查看自己电脑是什…

    2022年5月16日
  • 王者荣耀:操作最难的三个英雄,快来看看有没有你的本命

    在王者荣耀当中的英雄肯定各领风骚,但是大部分英雄还是在一个框架创作出来,也就造成有一部分英雄的操作会花里胡哨,一部分英雄无脑操作,那么今天小编盘点的三名蒂花之秀英雄,看看有没有你的…

    2022年9月21日
  • CSGO进入国服的代码

    随着csgo这类游戏的推出越来越多的人在该游戏里面畅游,但是有些人还是分不清国服与国际服二者的区别。 一般来说刚开始下载游戏的时候都是进入到国际服当中,因为随着游戏在中国的持续爆火…

    2022年7月17日
  • 热血传奇:装备不走寻常路,一人扛两战士!奇葩法师

    在《血之传说》中,道士和法师的背负能力和输出能力都不如武士。 与生俱来的低血量,让很多法师在与同级别的武者交手时,都变得脆弱如纸。 两名武者斩下,小法直接清空了血条,不管盾牌再厚。…

    2022年7月9日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息