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下线程之间的共享和释放示例
May 04 Python
Python3中使用PyMongo的方法详解
Jul 28 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
Dec 14 Python
Python使用pylab库实现绘制直方图功能示例
Jun 01 Python
pycharm重置设置,恢复默认设置的方法
Oct 22 Python
python多线程调用exit无法退出的解决方法
Feb 18 Python
Python操作rabbitMQ的示例代码
Mar 19 Python
vim自动补全插件YouCompleteMe(YCM)安装过程解析
Oct 21 Python
pygame实现俄罗斯方块游戏(基础篇2)
Oct 29 Python
关于Python字符串显示u...的解决方式
Mar 06 Python
利用Python裁切tiff图像且读取tiff,shp文件的实例
Mar 10 Python
Python程序慢的重要原因
Sep 04 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正则删除html代码中class样式属性的方法
2017/05/24 PHP
浅谈PHP SHA1withRSA加密生成签名及验签
2019/03/18 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
2019/10/03 PHP
Laravel 读取 config 下的数据方法
2019/10/13 PHP
AJAX使用了UpdatePanel后无法使用alert弹出脚本
2010/04/02 Javascript
jQuery boxy弹出层插件中文演示及使用讲解
2011/02/24 Javascript
js精度溢出解决方案
2012/12/02 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
window.onload使用指南
2015/09/13 Javascript
JQuery点击事件回到页面顶部效果的实现代码
2016/05/24 Javascript
AngularJS基础 ng-keydown 指令简单示例
2016/08/02 Javascript
JAVA中截取字符串substring用法详解
2017/04/14 Javascript
解决vue 打包发布去#和页面空白的问题
2018/09/04 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
2019/03/13 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
python3.0 字典key排序
2008/12/24 Python
Python中的urllib模块使用详解
2015/07/07 Python
python获取当前运行函数名称的方法实例代码
2017/04/06 Python
Python数据抓取爬虫代理防封IP方法
2018/12/23 Python
python opencv摄像头的简单应用
2019/06/06 Python
python循环定时中断执行某一段程序的实例
2019/06/29 Python
Python实现K折交叉验证法的方法步骤
2019/07/11 Python
为什么相对PHP黑python的更少
2020/06/21 Python
python 多线程共享全局变量的优劣
2020/09/24 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
Origins悦木之源香港官网:雅诗兰黛集团高端植物护肤品牌
2018/03/21 全球购物
说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
2012/05/24 面试题
市场营销个人求职信范文
2014/02/02 职场文书
2014年冬季防火方案
2014/05/21 职场文书
三严三实对照检查材料范文
2014/09/23 职场文书
大学生国庆节65周年演讲稿范文
2014/09/25 职场文书
校园新闻稿范文
2015/07/18 职场文书
2016年五四青年节校园广播稿
2015/12/17 职场文书
话题作文之诚信
2019/11/28 职场文书
python pygame入门教程
2021/06/01 Python
vue判断按钮是否可以点击
2022/04/09 Vue.js