读BeautifulSoup官方文档之html树的搜索(1)
之前介绍了有关的四个对象以及他们的属性, 但是一般情况下要在杂乱的html中提取我们所需的tag(tag中包含的信息)是比较复杂的, 现在我们可以来看看到底有些什么搜索的方法.
最主要的两个方法当然是find_all()和find(), 两者大致思路相同, 只不过一个前者返回符合条件的所有tags, 后者只返回一个tag. 我们先仔细看看find_all.
Signature: find_all(name, attrs, recursive, string, limit, **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参数
soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>] soup.find_all(href=re.compile("elsie"))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>] data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
data_soup.find_all(data-foo="value")
# SyntaxError: keyword can't be an expression soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">three</a>] def not_lacie(href):
return href and not re.compile("lacie").search(href)
soup.find_all(href=not_lacie)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <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, 其他没区别, 这里就不重复了...
读BeautifulSoup官方文档之html树的搜索(1)的更多相关文章
- 读BeautifulSoup官方文档之html树的搜索(2)
除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的 ...
- 读BeautifulSoup官方文档之html树的打印
prettify()能返回一个格式良好的html的Unicode字符串 : markup = '<a href="http://example.com/">I link ...
- 读BeautifulSoup官方文档之html树的修改
修改html树无非是对其中标签的改动, 改动标签的名字(也就是类型), 属性和标签里的内容... 先讲这边提供了很方便的方法来对其进行改动... soup = BeautifulSoup('<b ...
- 读BeautifulSoup官方文档之与bs有关的对象和属性(1)
自从10号又是5天没更, 是, 我再一次断更... 原因是朋友在搞python, 老问我问题, 我python也是很久没碰了, 于是为了解决他的问题, 我只能重新开始研究python, 为了快速找回感 ...
- 读BeautifulSoup官方文档之与bs有关的对象和属性(2)
上一节说到tag, 这里接着讲, tag有个属性叫做string, tag.string其实就是我们要掌握的四个对象中的第二个 ---- NavigableString, 它代表的是该tag内的te ...
- 读BeautifulSoup官方文档之与bs有关的对象和属性(3)
上一节说到.string的条件很苛刻, 如果某个tag里面包含了超过一个children, 就会返回None, 但是这里提供另外一种方式 .strings, 它返回的是一个generator, 比如对 ...
- 读vue-cli3 官方文档的一些学习记录
原来一直以为vue@cli3 就是创建模板的工具,读了官方文档才知道原来这么有用,不少配置让我长见识了 Prefetch 懒加载配置 懒加载相信大家都是知道的,使用Import() 语法就可以在需要的 ...
- Beautifulsoup官方文档
Beautiful Soup 中文文档 原文 by Leonard Richardson (leonardr@segfault.org) 翻译 by Richie Yan (richieyan@gma ...
- 读jQuery官方文档:$(document).ready()与避免冲突
$(document).ready() 通常你想在DOM结构加载完毕之后才执行相关脚本.使用原生JavaScript,你可能调用window.onload = function() { ... }, ...
随机推荐
- USB 3.0规范中译本 第10章 集线器,主机下行口以及设备上行口规范
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章描述USB 3.0 集线器的体系结构要求.本章还描述主机下行口和集线器下行口之间功能性的不同之处,以及设 ...
- jquery file upload示例
原文链接:http://blog.csdn.net/qq_37936542/article/details/79258158 jquery file upload是一款实用的上传文件插件,项目中刚好用 ...
- Cocos2d-x 3.2 Lua演示样例FontTest(字体測试)
Cocos2d-x 3.2 Lua演示样例FontTest(字体測试) 本篇博客介绍Cocos2d-x 3.2中Lua測试项目中的FontTest样例,主要使用了字体文件来创建我们想要的字体样式: 第 ...
- Linux开发环境搭建与使用系列教程
00.Linux开发环境搭建与使用1——Linux简史 01.Linux开发环境搭建与使用2——Linux系统(ubuntu)安装方案 02.Linux开发环境搭建与使用3——通过虚拟机安装系统(ub ...
- .net core 下的分布式事务锁
原文:.net core 下的分布式事务锁 目录 系统分布式锁的用法 锁的实现 锁的使用 API内的范例: 引用链接 系统分布式锁的用法 公司框架新增功能分布式锁: 锁的性能之王: 缓存 > Z ...
- 第六章:任务执行——Java并发编程实战
任务:通常是一些抽象的且离散的工作单元.大多数并发应用程序都是围绕"任务执行"来构造的,把程序的工作分给多个任务,可以简化程序的组织结构便于维护 一.在线程中执行任务 任务的独立性 ...
- 囚徒困境、价格大战与 iPhone 的价格
静态/动态,完全/不完全: 完全信息静态博弈: 不完全信息静态博弈: 完全信息动态博弈: 不完全信息动态博弈: 囚徒困境实际上反映了一个深刻的哲学问题:个人利益与集体利益的矛盾.个人为了自己利益的最大 ...
- 【u216】A+B Problem(aplusb)
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 对于给定的A和B,求A+B的值. [输入格式] 输入文件aplusb.in的第1行为一个整数A,第2行 ...
- NOIP模拟 Date - Tarjan
题目描述 小Y和小Z好不容易有机会相见啦,可是邪恶的小H却不想让他们相见.现在有一些城市,城市之间有双向路径相连,有路径相连的城市之间可以互相到达.小H可以任意选择一条路径,然后用他的邪恶力量污染这条 ...
- reduce 阶段遍历对象添加到ArrayList中的问题
起初遍历values时直接把对象添加到集合中,后来输出结果和预期不符,debug时发现添加到集合中的对象的值全部是最后一个对象的值,网上百度了下,发现是reduce阶段对象重用的问题,reduce阶段 ...