Python利用Beautiful Soup模块搜索内容详解


Posted in Python onMarch 29, 2017

前言

我们将利用 Beautiful Soup 模块的搜索功能,根据标签名称、标签属性、文档文本和正则表达式来搜索。

搜索方法

Beautiful Soup 内建的搜索方法如下:

  • find()
  • find_all()
  • find_parent()
  • find_parents()
  • find_next_sibling()
  • find_next_siblings()
  • find_previous_sibling()
  • find_previous_siblings()
  • find_previous()
  • find_all_previous()
  • find_next()
  • find_all_next()

使用 find() 方法搜索

首先还是需要建立一个 HTML 文件用来做测试。

<html>
<body>
<div class="ecopyramid">
 <ul id="producers">
 <li class="producerlist">
  <div class="name">plants</div>
  <div class="number">100000</div>
 </li>
 <li class="producerlist">
  <div class="name">algae</div>
  <div class="number">100000</div>
 </li>
 </ul>
 <ul id="primaryconsumers">
 <li class="primaryconsumerlist">
  <div class="name">deer</div>
  <div class="number">1000</div>
 </li>
 <li class="primaryconsumerlist">
  <div class="name">rabbit</div>
  <div class="number">2000</div>
 </li>
 </ul>
 <ul id="secondaryconsumers">
 <li class="secondaryconsumerlist">
  <div class="name">fox</div>
  <div class="number">100</div>
 </li>
 <li class="secondaryconsumerlist">
  <div class="name">bear</div>
  <div class="number">100</div>
 </li>
 </ul>
 <ul id="tertiaryconsumers">
 <li class="tertiaryconsumerlist">
  <div class="name">lion</div>
  <div class="number">80</div>
 </li>
 <li class="tertiaryconsumerlist">
  <div class="name">tiger</div>
  <div class="number">50</div>
 </li>
 </ul>
</div>
</body>
</html>

我们可以通过 find() 方法来获得 <ul> 标签,默认情况下会得到第一个出现的。接着再获取 <li> 标签,默认情况下还是会得到第一个出现的,接着获得 <div> 标签,通过输出内容来验证是否获取了第一个出现的标签。

from bs4 import BeautifulSoup
with open('search.html','r') as filename:
 soup = BeautifulSoup(filename,'lxml')
first_ul_entries = soup.find('ul')
print first_ul_entries.li.div.string

find() 方法具体如下:

find(name,attrs,recursive,text,**kwargs)

正如上代码所示,find() 方法接受五个参数:name、attrs、recursive、text 和 **kwargs 。name 、attrs 和 text 参数都可以在 find() 方法充当过滤器,提高匹配结果的精确度。

搜索标签

除了上面代码的搜索 <ul> 标签外,我们还可以搜索 <li> 标签,返回结果也是返回出现的第一个匹配内容。

tag_li = soup.find('li')
# tag_li = soup.find(name = "li")
print type(tag_li)
print tag_li.div.string

搜索文本

如果我们只想根据文本内容来搜索的话,我们可以只传入文本参数 :

search_for_text = soup.find(text='plants')
print type(search_for_text)
<class 'bs4.element.NavigableString'>

返回的结果也是 NavigableString 对象 。

根据正则表达式搜索

如下的一段 HTML 文本内容

<div>The below HTML has the information that has email ids.</div>
 abc@example.com 
<div>xyz@example.com</div> 
 <span>foo@example.com</span>

可以看到 abc@example 邮件地址并没有包括在任何标签内,这样就不能根据标签来找到邮件地址了。这个时候,我们可以使用正则表达式来进行匹配。

email_id_example = """
 <div>The below HTML has the information that has email ids.</div>
 abc@example.com
 <div>xyz@example.com</div>
 <span>foo@example.com</span>
 """
email_soup = BeautifulSoup(email_id_example,'lxml')
print email_soup
# pattern = "\w+@\w+\.\w+"
emailid_regexp = re.compile("\w+@\w+\.\w+")
first_email_id = email_soup.find(text=emailid_regexp)
print first_email_id

在使用正则表达式进行匹配时,如果有多个匹配项,也是先返回第一个。

根据标签属性值搜索

可以通过标签的属性值来搜索:

search_for_attribute = soup.find(id='primaryconsumers')
print search_for_attribute.li.div.string

根据标签属性值来搜索对大多数属性都是可用的,例如:id、style 和 title 。

但是对以下两种情况会有不同:

  • 自定义属性
  • 类 ( class ) 属性

我们不能再直接使用属性值来搜索了,而是得使用 attrs 参数来传递给 find() 函数。

根据自定义属性来搜索

在 HTML5 中是可以给标签添加自定义属性的,例如给标签添加 属性。

如下代码所示,如果我们再像搜索 id 那样进行操作的话,会报错的,Python 的变量不能包括 - 符号。

customattr = """
 <p data-custom="custom">custom attribute example</p>
   """
customsoup = BeautifulSoup(customattr,'lxml')
customsoup.find(data-custom="custom")
# SyntaxError: keyword can't be an expression

这个时候使用 attrs 属性值来传递一个字典类型作为参数进行搜索:

using_attrs = customsoup.find(attrs={'data-custom':'custom'})
print using_attrs

基于 CSS 中的 类 进行搜索

对于 CSS 的类属性,由于在 Python 中 class 是个关键字,所以是不能当做标签属性参数传递的,这种情况下,就和自定义属性一样进行搜索。也是使用 attrs 属性,传递一个字典进行匹配 。

除了使用 attrs 属性之外,还可以使用 class_ 属性进行传递,这样与 class 区别开了,也不会导致错误。

css_class = soup.find(attrs={'class':'producerlist'})
css_class2 = soup.find(class_ = "producerlist")
print css_class
print css_class2

使用自定义的函数搜索

可以给 find() 方法传递一个函数,这样就会根据函数定义的条件进行搜索。

函数应该返回 true 或者是 false 值。

def is_producers(tag):
 return tag.has_attr('id') and tag.get('id') == 'producers'
tag_producers = soup.find(is_producers)
print tag_producers.li.div.string

代码中定义了一个 is_producers 函数,它将检查标签是否具体 id 属性以及属性值是否等于 producers,如果符合条件则返回 true ,否则返回 false 。

联合使用各种搜索方法

Beautiful Soup 提供了各种搜索方法,同样,我们也可以联合使用这些方法来进行匹配,提高搜索的准确度。

combine_html = """
 <p class="identical">
  Example of p tag with class identical
 </p>
 <div class="identical">
  Example of div tag with class identical
 <div>
 """
combine_soup = BeautifulSoup(combine_html,'lxml')
identical_div = combine_soup.find("div",class_="identical")
print identical_div

使用 find_all() 方法搜索

使用 find() 方法会从搜索结果中返回第一个匹配的内容,而 find_all() 方法则会返回所有匹配的项。

find() 方法中用到的过滤项,同样可以用在 find_all() 方法中。事实上,它们可以用到任何搜索方法中,例如:find_parents()find_siblings() 中 。

# 搜索所有 class 属性等于 tertiaryconsumerlist 的标签。
all_tertiaryconsumers = soup.find_all(class_='tertiaryconsumerlist')
print type(all_tertiaryconsumers)
for tertiaryconsumers in all_tertiaryconsumers:
 print tertiaryconsumers.div.string

find_all() 方法为 :

find_all(name,attrs,recursive,text,limit,**kwargs)

它的参数和 find() 方法有些类似,多个了 limit 参数。limit 参数是用来限制结果数量的。而 find() 方法的 limit 就是 1 了。

同时,我们也能传递一个字符串列表的参数来搜索标签、标签属性值、自定义属性值和 CSS 类。

# 搜索所有的 div 和 li 标签
div_li_tags = soup.find_all(["div","li"])
print div_li_tags
print
# 搜索所有类属性是 producerlist 和 primaryconsumerlist 的标签
all_css_class = soup.find_all(class_=["producerlist","primaryconsumerlist"])
print all_css_class
print

搜索相关标签

一般情况下,我们可以使用 find()find_all() 方法来搜索指定的标签,同时也能搜索其他与这些标签相关的感兴趣的标签。

搜索父标签

可以使用 find_parent() 或者 find_parents() 方法来搜索标签的父标签。

find_parent() 方法将返回第一个匹配的内容,而 find_parents() 将返回所有匹配的内容,这一点与 find() find_all() 方法类似。

# 搜索 父标签
primaryconsumers = soup.find_all(class_='primaryconsumerlist')
print len(primaryconsumers)
# 取父标签的第一个
primaryconsumer = primaryconsumers[0]
# 搜索所有 ul 的父标签
parent_ul = primaryconsumer.find_parents('ul')
print len(parent_ul)
# 结果将包含父标签的所有内容
print parent_ul
print
# 搜索,取第一个出现的父标签.有两种操作
immediateprimary_consumer_parent = primaryconsumer.find_parent()
# immediateprimary_consumer_parent = primaryconsumer.find_parent('ul')
print immediateprimary_consumer_parent

搜索同级标签

Beautiful Soup 还提供了搜索同级标签的功能。

使用函数 find_next_siblings() 函数能够搜索同一级的下一个所有标签,而 find_next_sibling() 函数能够搜索同一级的下一个标签。

producers = soup.find(id='producers')
next_siblings = producers.find_next_siblings()
print next_siblings

同样,也可以使用 find_previous_siblings() find_previous_sibling() 方法来搜索上一个同级的标签。

搜索下一个标签

使用 find_next() 方法将搜索下一个标签中第一个出现的,而 find_next_all() 将会返回所有下级的标签项。

# 搜索下一级标签
first_div = soup.div
all_li_tags = first_div.find_all_next("li")
print all_li_tags

搜索上一个标签

与搜索下一个标签类似,使用 find_previous()find_all_previous() 方法来搜索上一个标签。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python3.3使用tkinter开发猜数字游戏示例
Mar 14 Python
python刷投票的脚本实现代码
Nov 08 Python
python基于windows平台锁定键盘输入的方法
Mar 05 Python
Python编写生成验证码的脚本的教程
May 04 Python
Python读取系统文件夹内所有文件并统计数量的方法
Oct 23 Python
python如何制作缩略图
Apr 30 Python
python中while和for的区别总结
Jun 28 Python
Python 装饰器原理、定义与用法详解
Dec 07 Python
Python使用os.listdir和os.walk获取文件路径
May 21 Python
如何在Python对Excel进行读取
Jun 04 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
Jul 03 Python
python+openCV对视频进行截取的实现
Nov 27 Python
windows系统下Python环境搭建教程
Mar 28 #Python
Python中Django 后台自定义表单控件
Mar 28 #Python
windows上安装Anaconda和python的教程详解
Mar 28 #Python
利用python爬取软考试题之ip自动代理
Mar 28 #Python
详解python调度框架APScheduler使用
Mar 28 #Python
Python中is与==判断的区别
Mar 28 #Python
Python利用Beautiful Soup模块创建对象详解
Mar 27 #Python
You might like
PHP取进制余数函数代码
2012/01/19 PHP
详解WordPress开发中get_header()获取头部函数的用法
2016/01/08 PHP
PHP 自动加载的简单实现(推荐)
2016/08/12 PHP
php基于单例模式封装mysql类完整实例
2016/10/18 PHP
PHP内置加密函数详解
2016/11/20 PHP
jQuery 加上最后自己的验证
2009/11/04 Javascript
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
页面加载完毕后滚动条自动滚动一定位置
2014/02/20 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
JavaScript 函数的执行过程
2016/05/09 Javascript
webpack独立打包和缓存处理详解
2017/04/03 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
2017/05/11 Javascript
angular select 默认值设置方法
2017/06/23 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
微信小程序云开发之新手环境配置
2019/05/16 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
[49:15]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第二场 1月19日
2021/03/11 DOTA
Python中几个比较常见的名词解释
2015/07/04 Python
python根据京东商品url获取产品价格
2015/08/09 Python
pandas中Timestamp类用法详解
2017/12/11 Python
Python中使用支持向量机(SVM)算法
2017/12/26 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
python控制nao机器人身体动作实例详解
2019/04/29 Python
Python使用numpy模块实现矩阵和列表的连接操作方法
2019/06/26 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
Python中bisect的用法及示例详解
2020/07/20 Python
HTML5中使用json对象的实例代码
2018/09/10 HTML / CSS
Too Faced官网:美国知名彩妆品牌
2017/03/07 全球购物
快时尚眼镜品牌,全国连锁眼镜店:LOHO眼镜生活
2018/10/08 全球购物
小区消防演习方案
2014/02/21 职场文书
毕业生如何写自我鉴定
2014/03/15 职场文书
医学生求职自荐书
2014/06/12 职场文书
2014年村计划生育工作总结
2014/11/14 职场文书
教师创先争优承诺书
2015/04/27 职场文书
MySQL注入基础练习
2021/05/30 MySQL
Win11 25163.1010更新补丁KB5016904推送,测试服务验证管道(附更新修复汇总)
2022/07/23 数码科技