读BeautifulSoup官方文档之html树的搜索(1)

之前介绍了有关的四个对象以及他们的属性, 但是一般情况下要在杂乱的html中提取我们所需的tag(tag中包含的信息)是比较复杂的, 现在我们可以来看看到底有些什么搜索的方法.

最主要的两个方法当然是find_all()和find(), 两者大致思路相同, 只不过一个前者返回符合条件的所有tags, 后者只返回一个tag. 我们先仔细看看find_all.

Signature: find_all(nameattrsrecursivestringlimit**kwargs)

find_all()会自动寻找调用标签的所有子孙(文档中说的, 其实还包括自生)中符合条件的, 经过试验, 以下如果用正则表达式做过滤器那么都默认区别大小写...

第一个参数是name, 它指的其实是tag的name, 你可以传一个字符串, 那么他会寻找tag的名字等于该字符串的tag, 你也可以传一组字符串, 那么它会寻找符合其中任何一个字符串的tag; 你也可以传入一个函数, 但是这个函数必须只有一个唯一的一个参数tag, 同时返回值必须是True 或者 False, 然后所以结果为True的标签被选中, 甚至可以传正则表达式.

soup.find_all(‘b‘)
# [<b>The Dormouse‘s story</b>]

import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b

soup.find_all(["a", "b"])
# [<b>The Dormouse‘s story</b>,
#  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

def has_class_but_no_id(tag):
    return tag.has_attr(‘class‘) and not tag.has_attr(‘id‘)
soup.find_all(has_class_but_no_id)
# [<p class="title"><b>The Dormouse‘s story</b></p>,
#  <p class="story">Once upon a time there were...</p>,
#  <p class="story">...</p>]

任何不被识别的参数都会被转化为对于tag的属性过滤器 (某些html5中的某些除外), 当然你也可以用字符串, 正则, 函数来过滤, 但是这里的函数必须要注意, 它的要求是唯一一个参数必须是你所要过滤的那个属性的值而不再是整个tag, 你也可以过滤tag的多个属性... 这就是所谓的keyword参数

 1 soup.find_all(id=‘link2‘)
 2 # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
 3
 4 soup.find_all(href=re.compile("elsie"))
 5 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
 6
 7 data_soup = BeautifulSoup(‘<div data-foo="value">foo!</div>‘)
 8 data_soup.find_all(data-foo="value")
 9 # SyntaxError: keyword can‘t be an expression
10
11 soup.find_all(href=re.compile("elsie"), id=‘link1‘)
12 # [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]
13
14 def not_lacie(href):
15     return href and not re.compile("lacie").search(href)
16 soup.find_all(href=not_lacie)
17 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
18 #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

当然过滤属性也可以用它的第二个参数attrs, 不像第一个参数,该参数必须是字典 :

data_soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]

本来tag的属性中有一个属性很常见叫做class, 但是class是python的关键字, 所以改成了class_, 用法和keyword参数的用法相同, 值得一提的是如果一个tag的类有多个值(一个tag同时属于多个类是合理的), 那么只要其中一个属性匹配了该tag, 该tag就被返回, 但是如果你尝试着匹配多个value, 那么一定要按照顺序, 如果顺序和tag的class中不同, 那么将匹配失败, 需要使用select而不是find_all() :

 1 soup.find_all(class_=re.compile("itl"))
 2 # [<p class="title"><b>The Dormouse‘s story</b></p>]
 3
 4 def has_six_characters(css_class):
 5     return css_class is not None and len(css_class) == 6
 6
 7 soup.find_all(class_=has_six_characters)
 8 # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
 9 #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
10 #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
11
12 css_soup.find_all("p", class_="body")
13 # [<p class="body strikeout"></p>]
14
15 css_soup.find_all("p", class_="strikeout body")
16 # []
17
18 css_soup.select("p.strikeout.body")
19 # [<p class="body strikeout"></p>]

第四个参数是string, 较老版本也叫作text... 单纯的使用该参数将寻找tag中的strings, 可以配合tag一起来用, 就能找到.string匹配这个条件的tag...

soup.find_all(string="Elsie")
# [u‘Elsie‘]

soup.find_all(string=["Tillie", "Elsie", "Lacie"])
# [u‘Elsie‘, u‘Lacie‘, u‘Tillie‘]

soup.find_all(string=re.compile("Dormouse"))
[u"The Dormouse‘s story", u"The Dormouse‘s story"]

def is_the_only_string_within_a_tag(s):
    """Return True if this string is the only child of its parent tag."""
    return (s == s.parent.string)

soup.find_all(string=is_the_only_string_within_a_tag)
# [u"The Dormouse‘s story", u"The Dormouse‘s story", u‘Elsie‘, u‘Lacie‘, u‘Tillie‘, u‘...‘]

soup.find_all("a", string="Elsie")
# [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]

limit参数很简单, 就是给该方法一个寻找数量上限, 比如limit=2, 那么找到2个之后就返回, 不再寻找, 所以当limit=1时, find_all()和find()相同.

recursive参数默认为True, 此时函数会匹配包括自己以及子孙tag, 如果设为False, 那么只匹配自己和孩子...

因为find_all()实在是太常用了, 所以这里还提供了简写方式 .

soup.find_all("a")
soup("a")

find()和find_all()除了上面提到的limit, 其他没区别, 这里就不重复了...

时间: 2024-11-03 22:45:05

读BeautifulSoup官方文档之html树的搜索(1)的相关文章

读BeautifulSoup官方文档之html树的搜索(2)

除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的... Signature: find_parents(name, attrs, string, limit, **kwargs) Signature: find_parent(name, attrs, string, **kwargs) Signature: find_next_siblings(

读BeautifulSoup官方文档之html树的修改

修改html树无非是对其中标签的改动, 改动标签的名字(也就是类型), 属性和标签里的内容... 先讲这边提供了很方便的方法来对其进行改动... 1 soup = BeautifulSoup('<b class="boldest">Extremely bold</b>') 2 tag = soup.b 3 4 tag.name = "blockquote" 5 tag['class'] = 'verybold' 6 tag['id'] = 1

读BeautifulSoup官方文档之html树的打印

prettify()能返回一个格式良好的html的Unicode字符串 : markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup) soup.prettify() # '<html>\n <head>\n </head>\n <body>\

读vue-cli3 官方文档的一些学习记录

原来一直以为[email protected] 就是创建模板的工具,读了官方文档才知道原来这么有用,不少配置让我长见识了 Prefetch 懒加载配置 懒加载相信大家都是知道的,使用Import() 语法就可以在需要的时候加载了,但是读了官方文档Prefetch一节后,发现事情并没有想象的那么简单. 文档写的很清楚,Prefetch是在空闲的时候就加载一些不着急的文件,并且import默认是加上了Prefetch的,也就是说你使用了import可能并不是你想要的结果(比如用户点击某个按钮才触发加

Beautifulsoup官方文档

Beautiful Soup 中文文档 原文 by Leonard Richardson ([email protected]) 翻译 by Richie Yan ([email protected]) ###如果有些翻译的不准确或者难以理解,直接看例子吧.### 英文原文点这里 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖析树(parse tree). 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作

第0001题 : 产生随机数(顺便读random模块官方文档)

看这个之前我准备先看一下random模块的官方文档... 在整个随机模块中,  最基础的就是random, 它产生一个 [0.0, 1.0)的浮点数. 这个模块下所有的函数实际上是绑定在一个叫做random.Ramdom的类的隐藏实例下的, 当然你可以自己实例化这个类从而得到新的随机数生成器, 同时random模块下还有一个叫做SystemRandom的类, 它使用系统函数 os.urandom()用操作系统提供的随机资源来来产生随机数.(不知所云...) 只挑了一部分看起来有用的函数... r

Mysql优化(出自官方文档) - 第八篇(索引优化系列)

目录 Mysql优化(出自官方文档) - 第八篇(索引优化系列) Optimization and Indexes 1 Foreign Key Optimization 2 Column Indexes 3 Column Indexes && Multiple-Column Indexes 4 Comparison of B-Tree and Hash Indexes 5 Use of Index Extensions 6 Invisible Indexes 7 Descending In

由浅入深Zookeeper详解(参考官方文档)

[老哥我最近接到个任务研究一下Zookeeper,对于我这个Linux运维领域的小菜鸟来说也是刚刚听到这个名字,为了养成良好的文档整理和学习能力,我人生第一次开通了博客并把这次的研究经历记录了下来,以后我会不定期的记录下来我对技术领域的探索,希望热爱Linux运维志同道合的兄弟们多指教,一同进步成长.(ps:我本人平时比较沉默,善于观察思考,对历史人物颇有见解,但是一旦说起话来就会滔滔不绝,谁让我曾经的梦想是当一名教师呢!哈哈!)同时,送给大家一句话,人生是一场马拉松比赛,只有坚持到最后的人,才

【苦读官方文档】2.Android应用程序基本原理概述

官方文档原文地址 应用程序原理 Android应用程序是通过Java编程语言来写.Android软件开发工具把你的代码和其它数据.资源文件一起编译.打包成一个APK文件,这个文档以.apk为后缀,保存了一个Android应用程序全部的内容.Android设备通过它来安装相应的应用. 一旦安装到设备上.每一个Android应用程序就执行在各自独立的安全沙盒中: Android系统是一个多用户的Linux系统.每一个应用都是一个用户. Android系统默认会给每一个应用分配一个唯一的用户ID(这个