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 相关文章推荐
Python类的基础入门知识
Nov 24 Python
跟老齐学Python之Import 模块
Oct 13 Python
如何解决django配置settings时遇到Could not import settings 'conf.local'
Nov 18 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
Jul 04 Python
基于python3 类的属性、方法、封装、继承实例讲解
Sep 19 Python
Python实现简易Web爬虫详解
Jan 03 Python
python实现图书借阅系统
Feb 20 Python
linux安装python修改默认python版本方法
Mar 31 Python
详解一种用django_cache实现分布式锁的方式
Sep 01 Python
详解Python可视化神器Yellowbrick使用
Nov 11 Python
python对一个数向上取整的实例方法
Jun 18 Python
python简单实现9宫格图片实例
Sep 03 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
SONY SRF-22W(33W)的电路分析和维修案例
2021/03/02 无线电
常用的PHP数据库操作方法(MYSQL版)
2011/06/08 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
php除数取整示例
2014/04/24 PHP
php获取开始与结束日期之间所有日期的方法
2016/11/29 PHP
javascript得到XML某节点的子节点个数的脚本
2008/10/11 Javascript
Mootools 1.2教程 正则表达式
2009/09/15 Javascript
JS对象与JSON格式数据相互转换
2012/02/20 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
js触发onchange事件的方法说明
2014/03/08 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
jQuery垂直多级导航菜单代码分享
2015/08/18 Javascript
javascript每日必学之多态
2016/02/23 Javascript
悬浮广告方法日常收集整理
2016/03/18 Javascript
完美解决spring websocket自动断开连接再创建引发的问题
2017/03/02 Javascript
如何使用Bootstrap 按钮实例详解
2017/03/29 Javascript
Angular2 组件交互实例详解
2017/08/24 Javascript
Vue三层嵌套路由的示例代码
2018/05/05 Javascript
JS通过位运算实现权限加解密
2018/08/14 Javascript
[04:26]DOTA2上海特锦赛小组赛第二日 TOP10精彩集锦
2016/02/27 DOTA
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
python通过伪装头部数据抵抗反爬虫的实例
2018/05/07 Python
python调用百度语音REST API
2018/08/30 Python
django foreignkey(外键)的实现
2019/07/29 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
python求前n个阶乘的和实例
2020/04/02 Python
Django通过json格式收集主机信息
2020/05/29 Python
英国足球店:UK Soccer Shop
2017/11/19 全球购物
对于没有初始化的变量的初始值可以作怎样的假定
2014/10/12 面试题
一些高难度的SQL面试题
2016/11/29 面试题
税务干部鉴定材料
2014/02/11 职场文书
中介业务员岗位职责
2014/04/09 职场文书
大学生党校培训心得体会
2014/09/11 职场文书
中小企业员工手册范本
2015/05/14 职场文书