一、 引言

在《第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问》介绍了BeautifulSoup对象的主要属性,通过这些属性可以访问标签、内容,但这种方法要么就只能访问符合条件的第一个对象,要么需要遍历访问对象,某些情况下不能通过指定特征快速定位标签和内容。本节将介绍使用BeautifulSoup提供的相关方法快速定位标签和内容的方法。本节继续复用《第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问》中的HTML文件和对象定义代码。

本节案例中介绍处理的c:\temp\s1.html文件内容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<style type="text/css"> .textline{color:blue;}</style>
<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>
<title>BeautifulSoups使用方法 - 老猿Python - CSDN博客 </title></head>
<body>
<h1>老猿Python</h1>
<div><p class="textline" name="line1"> 老猿Python首行</p></div>
<div>
<h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython" /> </h2>
<h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython" /> </h3>
</div>
</body></html>

创建soup对象的代码如下:

>>> from bs4 import BeautifulSoup
>>> def getsoup():
fp = open(r'c:\temp\s1.html',encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
fp.close()
print(soup)
return soup >>> soup=getsoup()

二、 方法find_all

find_all() 方法搜索当前标签的所有子节点,并判断是否符合过滤器的条件,非标签标记的字符串对象会被自动忽略掉。

1、 调用语法:find_all( name , attrs , recursive , string ,limit, **kwargs )

2、 name 参数:匹配过滤器,用于查找所有名字满足name过滤器 的标签。 过滤器有几种类型:

1)字符串:传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的标签名,注意是完整匹配,不是模糊匹配;

>>> soup.find_all('link')
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]
>>>

2)正则表达式:传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配标签名。注意在这个地方传入必须是re.compile的匹配模式,如果是匹配字符串Python会认为是字符串匹配。

>>> soup.find_all(re.compile('h[1-2]'))
[<h1>老猿Python</h1>, <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>]

3)列表:传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回;

>>> soup.find_all(['h1','h2'])
[<h1>老猿Python</h1>, <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>]
>>>

4)True:True 可以匹配任何标签,将查找所有的标签;

5)方法:传一个方法,该方法只有一个标签参数,通过这个方法对标签进行一些校验,满足条件返回 True 表示当前元素匹配并且被找到,如果不是则返回 False。如:

>>> def findline(tag):

    if tag==None: return False
content=tag.attrs.get('name')
if content==None:return False
return re.match('line',content)!=None >>> soup.find_all(findline)
[<p class="textline" name="line1"> 老猿Python首行</p>]
>>>

Beautiful Soup官网文档地址:https://beautifulsoup.readthedocs.io/zh_CN/latest/给了个例子:

def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')

将这个方法作为参数传入 find_all() 方法,将得到所有有class属性但无id属性的标签。

3、 kwargs参数

如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字标签的属性来搜索。如包含一个名字为 id 的参数,Beautiful Soup会搜索每个标签的”id”属性。

搜索方法语法如下:

属性id=匹配过滤器

其中属性id要求是个合法的Python标识符,否则需要使用attrs参数才能进行匹配。匹配过滤器与name参数类似,稍有差别,主要是不支持列表方式传参,同时其匹配的内容是属性id对应的值,而不是标签或属性id,匹配是去查看对应属性的值是否满足条件。

1)根据属性值的字符串来匹配,注意是必须完全相同,如:

>>> soup.find_all(rel='canonical')
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]

2)根据属性值的正则表达式使用match来匹配,如:

>>> soup.find_all(href=re.compile('.*'))
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>, <a href="https://blog.csdn.net/LaoYuanPython"></a>, <a href="https://blog.csdn.net/LaoYuanPython"></a>]
>>>

3)属性ID=True来匹配所有有该属性的标签,如:

>>> soup.find_all(rel=True)
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]
>>> soup.find_all(href=True)
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>, <a href="https://blog.csdn.net/LaoYuanPython"></a>, <a href="https://blog.csdn.net/LaoYuanPython"></a>]
>>>

4)方法:传一个方法,该方法只有一个参数,这个参数在调用时传递的实参时对应属性ID的属性值,通过这个方法对属性值进行一些校验,满足条件返回 True 表示当前元素匹配并且被找到,如果不是则返回 False

>>> def gethrefinludeaticle(value):
if value==None:return False
return re.findall('article',value) >>> soup.find_all(href=gethrefinludeaticle)
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]
>>>

注意:经老猿验证测试,发现在校验函数调用前,系统并没有先进行属性id的匹配成功再调用校验函数,而是所有标签属性匹配失败也会进入校验函数再校验,此时因为匹配失败value为None,因此对校验函数的参数进行None的判断非常重要。如果我们将value的情况输出,可以清楚看到函数的调用情况。如:

>>> def gethrefinludeaticle(value):
if value==None:
print("None")
return False
else:print(value)
return re.findall('article',value) >>> soup.find_all(href=gethrefinludeaticle)
None
None
None
https://blog.csdn.net/LaoYuanPython/article/details/95360624
None
None
None
None
None
None
None
https://blog.csdn.net/LaoYuanPython
None
None
https://blog.csdn.net/LaoYuanPython
None
None
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]
>>>

5)属性id为Python关键字class的匹配

按照CSS类名搜索tag的功能非常实用,但标识CSS类名的关键字 class 在Python中是保留字,使用 class 做参数会导致语法错误。

可以通过给class加下划线变成 class_进行搜索,如:

>>> soup.find_all(class='textline')
SyntaxError: invalid syntax
>>> soup.find_all(class_='textline')
[<p class="textline" name="line1"> 老猿Python首行</p>]

由于tag的 class 属性是 多值属性 .按照CSS类名搜索tag时,可以分别搜索tag中的每个CSS类名,如:

css_soup = BeautifulSoup('<p class="body strikeout"></p>')
css_soup.find_all("p", class_="strikeout")
# [<p class="body strikeout"></p>] css_soup.find_all("p", class_="body")
# [<p class="body strikeout"></p>]
搜索 class 属性时也可以通过CSS值完全匹配: css_soup.find_all("p", class_="body strikeout")
# [<p class="body strikeout"></p>]

4、 attrs参数

根据属性id和属性值的字典来匹配,可以使用“attrs=字典”,字典的元素的键是带引号的标签属性id,在属性id不是一个合法的Python标识符情况下,可以使用这种方法来匹配。根据老猿的测试验证,注意:class不能再加下划线,字典的值可以是上面所有的匹配方法,多个字典元素是与的关系,即要找到的标签必须具有字典中所有元素对应的内容。这可是网上的资料及beatifulsoap官网都没介绍。如:

>>> def gethrefinludeaticle(value):
if value==None: return False
return re.findall('article',value) >>> soup.find_all(attrs={'href':gethrefinludeaticle,'rel':'canonical'})
[<link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>]
>>> soup.find_all(attrs={'class':re.compile('.*')}) [<p class="textline" name="line1"> 老猿Python首行</p>]
>>> soup.find_all(attrs={'class_':re.compile('.*')}) #class不能加下划线 []
>>>

5、 recursive参数

调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。

6、 string参数

通过 string 参数可以搜搜文档中的字符串内容。与 name 参数的可选值一样, string 参数接受 字符串 , 正则表达式 , 列表, True 。

新版本该参数名为string,老版本中为text,根据老猿的验证这两个参数使用效果是一样的,不过建议使用string。 如:

>>> soup.find_all(text=re.compile('.*'))

['html', '\n', '\n', '\t.textline{color:blue;}', '\n', '\n', 'BeautifulSoups使用方法 - 老猿Python - CSDN博客 ', '\n', '\n', '老猿Python', '\n', ' 老猿Python首行', '\n', '\n', '老猿Python第二行', ' ', '\n', '老猿Python第三行', ' ', '\n', '\n', '\nkeyword 参数\n如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.\t']

>>> soup.find_all(string=re.compile('.*'))

['html', '\n', '\n', '\t.textline{color:blue;}', '\n', '\n', 'BeautifulSoups使用方法 - 老猿Python - CSDN博客 ', '\n', '\n', '老猿Python', '\n', ' 老猿Python首行', '\n', '\n', '老猿Python第二行', ' ', '\n', '老猿Python第三行', ' ', '\n', '\n', '\nkeyword 参数\n如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.\t']

7、 limit 参数

该参数在官网的方法定义中没有,但后面参数介绍中有,经过验证是可以使用的,因此老猿将其补充到参数中去了。使用 limit 参数限制返回结果的数量,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果。

8、 返回值

find_all的返回值是一个符合条件的html元素列表,每个元素就是一个符合条件的html元素。find_all()只搜索当前节点的所有子节点,孙子节点等。

三、 find_all方法的简写使用

find_all() 是Beautiful Soup中最常用的搜索方法,所以Beautiful Soup定义了它的缩写方法。具体缩写方式为:

将“BeautifulSoup对象.find_all(参数)” 缩写为“BeautifulSoup对象(参数)”

如代码:soup.find_all(“a”)与soup(“a”)是等价的,soup.title.find_all(string=True)与soup.title(string=True)等价。

四、 find

find() 搜索当前节点的所有子节点,孙子节点等是否有满足条件的元素,有则返回第一个符合条件的内容。

1. 调用语法:

find( name , attrs , recursive , string , **kwargs );

2. 语法释义:

find的几个参数与find_all中同名参数是一样的,参数含义也是一样,只是比find_all少了一个limit参数。而返回值是直接返回第一个满足条件的html元素。find_all() 方法没有找到目标是返回空列表,find() 方法找不到目标时返回 None 。某种程度上讲,find类似于find_all中参数limit=1的调用。

3.通过“对象.标签名”访问是“对象.find(”标签名”)”的简写,如:soup.head.title是soup.find(“head”).find(“title”)的简写。

五、 find_parents() 和 find_parent()

find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容。

  1. 调用语法:

    find_parents( name , attrs , recursive , string , **kwargs )

    find_parent( name , attrs , recursive , string , **kwargs )
  2. 语法释义

    find_parents() 和 find_parent()几个参数与find_all中同名参数是一样的,参数含义也是一样,只是比find_all少了一个limit参数。

    find_parents搜索父辈节点的方法实际上就是对 parents 属性的迭代搜索,返回值是一个列表。find_parent就是返回第一个符合条件的父节点的html元素,与parent属性含义是一样,只是parent只能通过“对象.parent”方式访问,而find_parent可以去父节点中查找满足条件的父节点。

六、 find_next_siblings() 和 find_next_sibling()

这2个方法通过 next_siblings 属性查找当前标签的所有后面解析的兄弟标签节点。

  1. 调用语法:

    find_next_siblings( name , attrs , recursive , string , **kwargs )

    find_next_sibling( name , attrs , recursive , string , **kwargs )
  2. 语法释义

    相关参数的含义与find_all的同名参数含义一致,find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点。

七、 find_previous_siblings() 和 find_previous_sibling()

这两个方法通过 previous_siblings 属性对当前tag的前面解析的兄弟tag节点进行迭代查找满足条件的节点。

  1. 调用语法:

    find_previous_siblings( name , attrs , recursive , string , **kwargs )

    find_previous_sibling( name , attrs , recursive , string , **kwargs )
  2. 语法释义

    这2个方法的参数与find_all中同名参数用途是一样的。find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点的列表,find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点。

八、 find_all_next() 和 find_next()

这2个方法通过 next_elements 属性对当前标签之后的标签和字符串进行迭代查找满足要求的数据。

  1. 调用语法:

    find_all_next ( name , attrs , recursive , string , **kwargs )

    find_next ( name , attrs , recursive , string , **kwargs )
  2. 语法释义:

    这2个方法的参数与find_all中同名参数用途是一样的。find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点。

九、 find_all_previous() 和 find_previous()

这2个方法通过 previous_elements 属性对当前节点前面的tag和字符串进行迭代查找符合条件的节点。

  1. 调用语法:

    find_all_previous( name , attrs , recursive , string , **kwargs )

    find_previous( name , attrs , recursive , string , **kwargs )
  2. 语法释义:

    这2个方法的参数与find_all中同名参数用途是一样的。find_all_previous () 方法返回所有符合条件的节点, find_previous 方法返回第一个符合条件的节点。

本节介绍了BeautifulSoup查找类的主要方法,通过这些方法可以找到符合条件的html元素。本节文档老猿在BeautifulSoup官网的基础之上验证测试之后整理而成,文档结构大部分内容与官网内容,但有老猿验证之后的一些比较独特的内容。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036

请大家多多支持,点赞、评论和加关注!谢谢!

第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容的更多相关文章

  1. 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容

    一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...

  2. 第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问

    一. 引言 在<第14.8节 Python中使用BeautifulSoup加载HTML报文>中介绍使用BeautifulSoup的安装.导入和创建对象的过程,本节介绍导入后利用Beauti ...

  3. 第14.8节 Python中使用BeautifulSoup加载HTML报文

    一. 引言 BeautifulSoup是一个三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能.阅读本节需要了解html相关的 ...

  4. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  5. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

  6. 第14.9节 Python中使用urllib.request+BeautifulSoup获取url访问的基本信息

    利用urllib.request读取url文档的内容并使用BeautifulSoup解析后,可以通过一些基本的BeautifulSoup对象输出html文档的基本信息.以博文<第14.6节 使用 ...

  7. 第9.11节 Python中IO模块文件打开读写操作实例

    为了对前面学习的内容进行一个系统化的应用,老猿写了一个程序来进行文件相关操作功能的测试. 一. 测试程序说明 该程序允许测试人员选择一个文件,自己输入文件打开模式.写入文件的位置以及写入内容,程序按照 ...

  8. 第9.10节 Python中IO模块其他文件操作属性和方法简介

    本文中所有案例中的fp都是使用open函数打开文件返回的一个文件对象,为了节省篇幅,大部分没有提供文件打开的代码. 一. 文件是否关闭的属性 属性名:closed 功用:判断文件是否关闭 示例: &g ...

  9. 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

随机推荐

  1. GROUP BY 分组后得到最新即时间最大的一条数据(需添加limit才可生效)

    当使用GROUP BY 分组,默认返回的数据是组中最小的记录即id最小的数据, 当开发中经常会需要分组后将最新的数据放在前面, 为了实现需求,使用了嵌套查询,分别使用order by来排序 SELEC ...

  2. 利用 Docker 构建一个简单的 java 开发编译环境

    目前 Java 语言的版本很多,除了常用的 Java 8,有一些遗留项目可能使用了 Java 7,也可能有一些比较新的的项目使用了 Java 10 以上的版本.如果想切换自己本地的 Java 开发环境 ...

  3. NO.A.0001——FIO工具使用教程

    一.FIO工具安装: 1.FIO地址: 官网地址:http://freecode.com/projects/fio/ 源码安装包:http://brick.kernel.dk/snaps/fio-2. ...

  4. mysql权限管理命令

    #创建用户 create user 'songwp' IDENTIFIED BY '1234' #用户授权 GRANT ALL ON DB01.* TO 'songwp' #撤销权限 REVOKE A ...

  5. NO.A.0009——day04——idea的安装及配置教程

    概述: 集成开发环境:IDE.开发工具Integrated Development Environment,IDE, 1.如果自己手洗衣服: 1. 准备一盆水 2. 放入衣服浸泡30分钟 3. 搓洗衣 ...

  6. linux下制作软件包安装服务器

    linux下的软件包在有网络的情况下比较好安装,在ubuntu下,更新sourcelist,然后使用apt-get就可以很方便的安装包,在centos下面,更新yum列表,然后使用yum也可以进行方便 ...

  7. flink1.10版本StreamGraph生成过程分析

    1.StreamGraph本质 本质就是按照用程序代码的执行顺序构建出来的用于向执行环境传输的流式图,并且可以支持可视化展示给用户的一种数据结构. 2.StreamGraph.StreamNode和S ...

  8. conda / cuda / screen 常用命令总结

    记录一些常用的 conda / cuda / screen 相关的命令,这些在跑深度学习代码时经常用到. conda 下面的命令在 Ubuntu 下的 4.8.3 版本 conda 均正确工作. 查看 ...

  9. 算法题目:北邮python 3-C 排队前进

    一道python作业的题目,比较有意思,题目如下: 题目描述 有 n 个人排队向一个方向前进,他们前进的速度并不一定相同. 最开始即 t=0 时,每个人的位置并不相同.可以把他们放在数轴上,设他们前进 ...

  10. 利用Vmware workstation安装MS-DOS使用Turbo C 2.0

    首先上各种软件的链接 链接:https://pan.baidu.com/s/1HfTDexiJSpioUnzKddUIyA 提取码:khtu 这个链接是压缩后的 链接:https://pan.baid ...