博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Python爬虫学习笔记5】Beautiful Soup库
阅读量:6141 次
发布时间:2019-06-21

本文共 5008 字,大约阅读时间需要 16 分钟。

Beautiful Soup 和 lxml 一样,是Python的一个HTML/XML的解析库,它可以借助网页的结构和属性等特性来解析网页。它和lxml有相当的功能,也有着不同之处:lxml只会局部遍历,而Beautiful Soup 是基于HTML DOM(Document Object Model)的,会载入整个文档来解析DOM树,因此时间和内存开销都会大很多,性能要低于lxml。

如下为一个解析器对比(包含正则):

解析工具 解析速度 使用难度
Beautiful Soup 最慢 最简单
lxml 简单
正则 最快 最难

即便如此,Beautiful Soup 的解析使用相对简单,其API非常人性化,支持CSS选择器、Python标准库HTML解析器,同时也支持 lxml 的 XML解析器,甚至容错性最好的html5lib解析器。所以说,利用好Beautiful Soup可以省去很多工作,提高解析效率。

安装方法

使用pip进行安装:pip install bs4

基本使用

1.使用基础

使用前需要先导入BeautifulSoup模块(属于bs4库),然后使用Beautiful(html,parse)实例化对象,传入的参数分别为待解析的html源码文本和解析器种类(如lxml,html.parse,xml或html5lib)。当实例化对象soup后,接下来就可以调用其各个方法和属性解析HTML代码了。

html = """
28607-113 微信支付大数据平台开发工程师(深圳) 技术类 1 深圳 2018-09-18
OMG097-自然语言处理工程师(北京) 技术类 3 北京 2018-09-18
18428-银行业务测试工程师(深圳)  技术类 1 深圳 2018-09-18
"""
##前期准备from bs4 import BeautifulSoup# 实例化对象soup = BeautifulSoup(html, 'lxml')
# 美观地输出HTML源代码文本
print
(bs.prettify())

2.find()与find_all()方法

这两个都是Soup解析方法中较为常用的用于检索获取特定节点的方法,其中find()方法用于获取一个节点,返回值为单个的Tag标签(如果存在,否则为None,当有多个满足时只返回第一个),而find_all()则是在find()的基础上返回所有符合条件的节点列表(没有满足的情况下返回空列表[])。

通常情况下,find_all()用得更为频繁,基本语法为:object = soup.find_all(Tag),下面以一系列示例来说明其用法。

##使用find_all()检索获取节点标签from bs4 import BeautifulSouphtml="""如上示例"""soup = BeautifulSoup(html, 'lxml')# 示例1——获取所有tr标签trs = soup.find_all('tr')for tr in trs:    print(type(tr))    #
print(tr)# 示例2——获取第2个tr标签tr = soup.find_all('tr',limit=2)[1] #参数limit用于限制返回个数为2个,由于是列表结构,第二个下标为1print(tr)# 示例3——获取所有class为even的tr标签trs = soup.find_all('tr',attrs={
'class':'even'}) #参数attrs用于属性过滤# 示例4——将所有id等于test,class也等于test的a标签提取出来aList = soup.find_all('a',attrs={
'class':'test','id':'test'})# 示例5——获取所有a标签的href属性aList = soup.find_all('a')for a in aList: href = a['href'] # 或href = a.attrs['href'],attrs为其属性字典 print(href)

3.select()方法

此方法为CSS选择器方法,即通过元素CSS选择表达式来筛选符合条件的节点,其返回的也是为一个列表。使用此方法前需要对CSS有一定的了解,在爬虫中我们只需要掌握以下几类基本的用法即可,其他具体的可以查阅相关网络资料(比如,

选择器 构成法 使用说明 示例 描述
通过标签名选择 tag 直接输入待选择的标签名 div 选择所有的div标签
通过类名选择 .class 在类名前面加一个. p.text 选择所有类为text的p标签
通过id选择 #id 在id名前加一个#号 #username 选择id为username的标签
组合选择1(全局选择)   将多个选择器方法叠加一起,同时用空格分开 p #poster 选择id为poster的p标签
组合选择2(特定选择)   当需要使用组合来选择直接子节点时,需要用’>’连接 div > input 选择div下的直接input标签
通过属性选择 [attrs=value] 通过在[]中指定属性表达式来选择,但不适用多属性 a[id=”link”] 选择id为link的a标签

在熟悉CSS选择器基本语法规则后,我们便可以通过soup的select(选择表达式)方法来获取相应的节点标签了。以上的 select 方法返回的结果都是列表形式,可以遍历或通过下标获取节点元素,然后用使用 get_text()(返回子孙非标签字符串) 方法来获取其文本内容。

下面仍以上述html代码为例,介绍select()的使用方法。

##使用select()方法检索获取节点from bs4 import BeautifulSouphtml="""如上示例"""soup = BeautifulSoup(html, 'lxml')# 示例1——获取所有tr标签trs = soup.select('tr')for tr in trs:    print(tr)# 示例2——获取第2个tr标签tr = soup.select('tr')[1]print(tr)# 示例3——获取所有class为even的tr标签trs = soup.select('tr[class="even"]')for tr in trs:    print(tr)# 示例4——将所有id等于test,class也等于test的a标签提取出来#由于CSS选择器无法直接选取同时满足两种条件的标签,故此目标无法完成,但可以通过二次选择来获取# 示例5——获取所有a标签的href属性aList= soup.select('a')for a in aList:    href = a['href']    print(href)

4.获取文本内容

在soup获取后的节点对象中,如要获取其文本内容,除了上文中提到的get_text()方法外,还可以使用如下的属性:

(1)string:获取某个标签下的非标签字符串,返回的为字符串。

(2)strings:获取某个标签下的子孙非标签字符串,返回的为生成器。

(3)stripped_string:获取某个标签下的子孙非标签字符串,会去掉空白字符,返回的为生成器。

仍以上述为例,使用示例如下:

##获取文本内容tr2 = soup.select('tr')[1]# 获取非标签字符串print(tr2.string)    #None# 获取子孙非标签字符串print(list(tr2.strings))    #['\n', 'OMG097-自然语言处理工程师(北京)', '\n', '技术类', '\n', '3', '\n', '北京', '\n', '2018-09-18', '\n']# 获取除去空白的子孙非标签字符串print(list(tr2.stripped_strings))    #['OMG097-自然语言处理工程师(北京)', '技术类', '3', '北京', '2018-09-18']
# 获取子孙非标签字符串,以普通字符串形式返回print(tr2.get_text())"""Output:OMG097-自然语言处理工程师(北京)技术类3北京2018-09-18"""

补充内容

1.Beautiful Soup中四个常用对象:

(1)Tag

即HTML中的一个个节点标签,如head、body、title、div、p和input等等。

(2)NavigatableString

获取标签后,我们利用其属性(如string属性)从标签得到它的内容所返回的这个对象就时NavigatableString。

(3)BeautifulSoup

BeautifulSoup 对象表示的是一个文档的全部内容,大部分时候可以把它当作 Tag 对象,其支持遍历文档树和搜索文档树中描述的大部分的方法,比如我们之前使用soup就是这种对象。

(4)Comment

Tag , NavigableString , BeautifulSoup 几乎覆盖了html和xml中的所有内容,但是有一类特殊对象——注释,而Comment就是用于获取这些内容的对象。实际上,Comment 对象是一个特殊的 NavigableString 对象。

html = "

"soup = BeautifulSoup(html)comment = soup.b.stringprint(comment) # ‘Hello World’

2.contents和children属性遍历文档树

在我们获取标签节点后,还可以通过contents和children两个属性来获取其下的子节点,二者的区别在于contents返回所有子节点列表,而children返回的是一个迭代器。

tr2 = soup.find_all('tr')[1]# 返回所有子节点的列表print(tr2.contents)"""Output:['\n', OMG097-自然语言处理工程师(北京), '\n', 技术类, '\n', 3, '\n', 北京, '\n', 2018-09-18, '\n']"""# 返回所有子节点的迭代器print(tr2.children)"""Output:
"""

 


转载于:https://www.cnblogs.com/Unikfox/p/9676177.html

你可能感兴趣的文章
任务调度(一)——jdk自带的Timer
查看>>
UIKit框架(15)PCH头文件
查看>>
整理看到的好的文档
查看>>
Linux磁盘管理和文件系统管理
查看>>
linux运维人员的成功面试总结案例分享
查看>>
Windows DHCP Server基于MAC地址过滤客户端请求实现IP地址的分配
查看>>
命令查询每个文件文件数
查看>>
《跟阿铭学Linux》第8章 文档的压缩与打包:课后习题与答案
查看>>
RAC表决磁盘管理和维护
查看>>
Apache通过mod_php5支持PHP
查看>>
发布一个TCP 吞吐性能测试小工具
查看>>
java学习:jdbc连接示例
查看>>
PHP执行批量mysql语句
查看>>
Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块
查看>>
Silverlight 如何手动打包xap
查看>>
建筑电气暖通给排水协作流程
查看>>
JavaScript面向对象编程深入分析(2)
查看>>
linux 编码转换
查看>>
POJ-2287 Tian Ji -- The Horse Racing 贪心规则在动态规划中的应用 Or 纯贪心
查看>>
Windows8/Silverlight/WPF/WP7/HTML5周学习导读(1月7日-1月14日)
查看>>