您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

爬虫利器 Beautiful Soup 之遍历文档

时间:2022-07-04 09:43:05  来源:  作者:VT漫步

Beautiful Soup 简介

Beautiful Soup 是一个可以从 html 或 XML 文件中提取数据的 Python/ target=_blank class=infotextkey>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 1
from bs4 import BeautifulSoup
# soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html><head><title>index</title></head><body>content</body></html>", "lxml") # 指定解析器
print(soup.head)

# 输出结果
<head><title>index</title></head>

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

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

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

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

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

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

html_doc = """
<html><head><title>index</title></head>
<body>
<p class="title"><b>首页</b></p>
<p class="mAIn">我常用的网站
<a href="https://www.google.com" class="website" id="google">Google</a>
<a href="https://www.baidu.com" class="website" id="baidu">Baidu</a>
<a href="https://cn.bing.com" class="website" id="bing">Bing</a>
</p>
<div><!--这是注释内容--></div>
<p class="content1">...</p>
<p class="content2">...</p>
</body>
"""

子节点

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

# demo 2
soup = BeautifulSoup(html_doc, "lxml");
p_tag = soup.p
print(p_tag.name)
print(p_tag["class"])
print(p_tag.attrs)

p_tag.name="myTag" # attrs 同样可被修改,操作同字典
print(p_tag)

#输出结果
p
['title']
{'class': ['title']}
<myTag class="title"><b>首页</b></myTag>

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

# demo 3
soup = BeautifulSoup(html_doc, "lxml");
print(soup.p.b)

#输出结果
<b>首页</b>

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

# demo 4
soup = BeautifulSoup(html_doc, "lxml");
a_tags=soup.find_all("a")
print(a_tags)

#输出结果
[<a class="website" href="https://www.google.com" id="google">Google</a>, <a class="website" href="https://www.baidu.com" id="baidu">Baidu</a>, <a class="website" href="https://cn.bing.com" id="bing">Bing</a>]

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

# demo 5
soup = BeautifulSoup(html_doc, "lxml");
head_tag=soup.head
print(head_tag)
print(head_tag.contents)

for child in head_tag.children:
	print("child is : ", child)

#输出结果
<head><title>index</title></head>
[<title>index</title>]
child is :  <title>index</title>

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

# demo 6
soup = BeautifulSoup(html_doc, "lxml");
head_tag=soup.head
for child in head_tag.descendants:
	print("child is : ", child)

# 输出结果
child is :  <title>index</title>
child is :  index

父节点

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

# demo 7
soup = BeautifulSoup(html_doc, "lxml");
title_tag=soup.title

print(title_tag.parent)
print(type(soup.html.parent))
print(soup.parent)

# 输出结果
<head><title>index</title></head>
<class 'bs4.BeautifulSoup'>
None

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

# demo 8
soup = BeautifulSoup(html_doc, "lxml");
a_tag=soup.a

for parent in a_tag.parents:
    print(parent.name)

# 输出结果
p
body
html
[document]

兄弟节点

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

# demo 9
soup = BeautifulSoup(html_doc, "lxml");
div_tag=soup.div

print(div_tag.next_sibling)
print(div_tag.next_sibling.next_sibling)

# 输出结果

<p class="content1">...</p>

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

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

# demo 10
soup = BeautifulSoup(html_doc, "lxml");
div_tag=soup.div

for pre_tag in div_tag.previous_siblings:
	print("pre_tag is : ", pre_tag)

# 输出结果
pre_tag is :  

pre_tag is :  <p class="main">我常用的网站
<a class="website" href="https://www.google.com" id="google">Google</a>
<a class="website" href="https://www.baidu.com" id="baidu">Baidu</a>
<a class="website" href="https://cn.bing.com" id="bing">Bing</a>
</p>
pre_tag is :  

pre_tag is :  <p class="title"><b>首页</b></p>
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 11
soup = BeautifulSoup(html_doc, "lxml");

head_tag=soup.head
print(head_tag.next_element)

title_tag=soup.title
print(title_tag.next_element)

# 输出结果
<title>index</title>
index

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

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

# demo 12
soup = BeautifulSoup(html_doc, "lxml");
div_tag=soup.div
for next_element in div_tag.next_elements:
	print("next_element is : ", next_element)

# 输出结果
next_element is :  这是注释内容
next_element is :  

next_element is :  <p class="content1">...</p>
next_element is :  ...
next_element is :  

next_element is :  <p class="content2">...</p>
next_element is :  ...
next_element is :  

next_element is :  

Beautiful Soup 总结

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

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



Tags:爬虫   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
360 AI搜索App上线:基于“爬虫”抓取和用户提交数据
IT之家 1 月 29 日消息,360 AI 搜索 App 上线各大手机应用商城,当前版本为 1.0.0,安装包大小 27.4M,暂时没有收费选项。IT之家从官方描述获悉,当用户在 360 AI 搜索中输入任何问...【详细内容】
2024-01-30  Search: 爬虫  点击:(60)  评论:(0)  加入收藏
Python分布式爬虫打造搜索引擎
简单分布式爬虫结构主从模式是指由一台主机作为控制节点负责所有运行网络爬虫的主机进行管理,爬虫只需要从控制节点那里接收任务,并把新生成任务提交给控制节点就可以了,在这个...【详细内容】
2024-01-25  Search: 爬虫  点击:(63)  评论:(0)  加入收藏
python 爬虫常用第三方库推荐
Python 是一种非常适合进行网络爬虫开发的语言,拥有丰富的第三方库和工具,可以方便快捷地实现各种爬虫需求。下面是好学编程总结的 Python 爬虫开发的一些常用步骤:1. 确定目标...【详细内容】
2023-12-29  Search: 爬虫  点击:(95)  评论:(0)  加入收藏
搜索引擎排名优化是针对蜘蛛爬虫还是对用户?
搜索引擎排名优化,这是一个让无数网站管理员、营销人员和创业者们既爱又恨的话题。有人认为它是提高网站知名度的关键,也有人觉得它不过是个劳神费力的无底洞。那么,这个看似神...【详细内容】
2023-12-28  Search: 爬虫  点击:(89)  评论:(0)  加入收藏
蜘蛛爬网络数据的用处•爬虫目的是什么
1.可以挖掘丰富资源:使用Baidu蜘蛛,可以挖掘互联网的无限资源。通过爬取各类网站,获得大量的比如新闻、文献、视频等等数据。如我们常常需要查找大量的文献资料来支撑我们的研...【详细内容】
2023-12-26  Search: 爬虫  点击:(70)  评论:(0)  加入收藏
哪些网站爬虫有兴趣?怎样吸引到蜘蛛爬虫?
怎样更好地吸引百度蜘蛛爬取网站?想让蜘蛛抓取网站内容,想要吸引蜘蛛的青睐,需要很多技巧,下面带大家一起来了解一下。1.新站提交文章链接网站是新站的话,百度蜘蛛自然是不太感兴...【详细内容】
2023-12-18  Search: 爬虫  点击:(101)  评论:(0)  加入收藏
学透这10个Python爬虫框架,轻松爬取一切数据
什么是Python爬虫框架?就像超市里有卖半成品的菜一样,Python爬虫工具也有半成品,就是Python爬虫框架。就是把一些常见的爬虫功能的代码先写好,然后留下一些借口。当我们在做不同...【详细内容】
2023-12-08  Search: 爬虫  点击:(236)  评论:(0)  加入收藏
移动端Python爬虫实战
移动端Python爬虫实战Python爬虫是指利用Python编程语言编写的程序,用于自动从互联网上获取信息。通过模拟人的行为,Python爬虫可以访问网页、抓取数据,并将数据保存到本地或...【详细内容】
2023-11-25  Search: 爬虫  点击:(230)  评论:(0)  加入收藏
Python爬虫神器:Beautiful Soup指南,轻松解析网页数据!
Beautiful Soup(简称BS4)是一种强大而灵活的HTML和XML解析库,广泛用于Python爬虫和数据采集中。这篇文章介绍 Beautiful Soup的功能和用法,并提供示例代码,帮助你更好地理解和应...【详细内容】
2023-10-22  Search: 爬虫  点击:(117)  评论:(0)  加入收藏
Python爬虫常用的库,这些你都用过吗?
在信息时代,数据是无处不在的宝藏。从网页内容、社交媒体帖子到在线商店的产品信息,互联网上存在着大量的数据等待被收集和分析。Python爬虫是一种强大的工具,用于从互联网上获...【详细内容】
2023-10-21  Search: 爬虫  点击:(106)  评论:(0)  加入收藏
▌简易百科推荐
一篇文章教会你使用Python中三种简单的函数
所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。一、函数简介所谓函数,就是指:把某些特定功能的代码组成为一个整体,这个整体就叫做函数。二、函数定义...【详细内容】
2024-04-11  Go语言进阶学习  微信公众号  Tags:Python   点击:(12)  评论:(0)  加入收藏
一篇文章带你了解Python的分布式进程接口
在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。一、前言在Thread和Process中,应当优...【详细内容】
2024-04-11  Go语言进阶学习    Tags:Python   点击:(10)  评论:(0)  加入收藏
Python 可视化:Plotly 库使用基础
当使用 Plotly 进行数据可视化时,我们可以通过以下示例展示多种绘图方法,每个示例都会有详细的注释和说明。1.创建折线图import plotly.graph_objects as go# 示例1: 创建简单...【详细内容】
2024-04-01  Python技术    Tags:Python   点击:(15)  评论:(0)  加入收藏
Python 办公神器:教你使用 Python 批量制作 PPT
介绍本文将介绍如何使用openpyxl和pptx库来批量制作PPT奖状。本文假设你已经安装了python和这两个库。本文的场景是:一名基层人员,要给一次比赛活动获奖的500名选手制作奖状,并...【详细内容】
2024-03-26  Python技术  微信公众号  Tags:Python   点击:(21)  评论:(0)  加入收藏
Python实现工厂模式、抽象工厂,单例模式
工厂模式是一种常见的设计模式,它可以帮助我们创建对象的过程更加灵活和可扩展。在Python中,我们可以使用函数和类来实现工厂模式。一、Python中实现工厂模式工厂模式是一种常...【详细内容】
2024-03-07  Python都知道  微信公众号  Tags:Python   点击:(38)  评论:(0)  加入收藏
不可不学的Python技巧:字典推导式使用全攻略
Python的字典推导式是一种优雅而强大的工具,用于创建字典(dict)。这种方法不仅代码更加简洁,而且执行效率高。无论你是Python新手还是有经验的开发者,掌握字典推导式都将是你技能...【详细内容】
2024-02-22  子午Python  微信公众号  Tags:Python技巧   点击:(43)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  编程技术汇    Tags:Python代码   点击:(44)  评论:(0)  加入收藏
Python开发者必备的八个PyCharm插件
在编写代码的过程中,括号几乎无处不在,以至于有时我们会拼命辨别哪个闭合括号与哪个开头的括号相匹配。这款插件能帮助解决这个众所周知的问题。前言在PyCharm中浏览插件列表...【详细内容】
2024-01-26  Python学研大本营  微信公众号  Tags:PyCharm插件   点击:(92)  评论:(0)  加入收藏
Python的Graphlib库,再也不用手敲图结构了
Python中的graphlib库是一个功能强大且易于使用的工具。graphlib提供了许多功能,可以帮助您创建、操作和分析图形对象。本文将介绍graphlib库的主要用法,并提供一些示例代码和...【详细内容】
2024-01-26  科学随想录  微信公众号  Tags:Graphlib库   点击:(95)  评论:(0)  加入收藏
Python分布式爬虫打造搜索引擎
简单分布式爬虫结构主从模式是指由一台主机作为控制节点负责所有运行网络爬虫的主机进行管理,爬虫只需要从控制节点那里接收任务,并把新生成任务提交给控制节点就可以了,在这个...【详细内容】
2024-01-25  大雷家吃饭    Tags:Python   点击:(63)  评论:(0)  加入收藏
站内最新
站内热门
站内头条