之前介绍了有关的四个对象以及他们的属性, 但是一般情况下要在杂乱的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参数

 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)的更多相关文章

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

    除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的 ...

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

    prettify()能返回一个格式良好的html的Unicode字符串 : markup = '<a href="http://example.com/">I link ...

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

    修改html树无非是对其中标签的改动, 改动标签的名字(也就是类型), 属性和标签里的内容... 先讲这边提供了很方便的方法来对其进行改动... soup = BeautifulSoup('<b ...

  4. 读BeautifulSoup官方文档之与bs有关的对象和属性(1)

    自从10号又是5天没更, 是, 我再一次断更... 原因是朋友在搞python, 老问我问题, 我python也是很久没碰了, 于是为了解决他的问题, 我只能重新开始研究python, 为了快速找回感 ...

  5. 读BeautifulSoup官方文档之与bs有关的对象和属性(2)

    上一节说到tag, 这里接着讲, tag有个属性叫做string, tag.string其实就是我们要掌握的四个对象中的第二个 ---- NavigableString,  它代表的是该tag内的te ...

  6. 读BeautifulSoup官方文档之与bs有关的对象和属性(3)

    上一节说到.string的条件很苛刻, 如果某个tag里面包含了超过一个children, 就会返回None, 但是这里提供另外一种方式 .strings, 它返回的是一个generator, 比如对 ...

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

    原来一直以为vue@cli3 就是创建模板的工具,读了官方文档才知道原来这么有用,不少配置让我长见识了 Prefetch 懒加载配置 懒加载相信大家都是知道的,使用Import() 语法就可以在需要的 ...

  8. Beautifulsoup官方文档

    Beautiful Soup 中文文档 原文 by Leonard Richardson (leonardr@segfault.org) 翻译 by Richie Yan (richieyan@gma ...

  9. 读jQuery官方文档:$(document).ready()与避免冲突

    $(document).ready() 通常你想在DOM结构加载完毕之后才执行相关脚本.使用原生JavaScript,你可能调用window.onload = function() { ... }, ...

随机推荐

  1. php date mktime 获取时间上的各种值

    echo date("Ymd",strtotime("now")), "\n"; echo date("Ymd",str ...

  2. IHookHelper的用法

    1.实例化IHookHelper 对象: IHookHelper m_hookHelper = new HookHelperClass();  m_hookHelper.Hook = this.axM ...

  3. 【42%】【hdu1166】排兵布阵(树状数组解法&&线段树解法)

    Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...

  4. 公布一个基于CSDN Code的学习測试仓库

    使用CSDN Code代码托管平台有一段时间了,今天新建立了一个公开的仓库https://code.csdn.net/smstong/learngit/tree/master,供大家測试合并请求等协作 ...

  5. [经典面试题]k节点一组旋转链表

    [题目] 给出一个链表和一个数k,比方链表1→2→3→4→5→6.k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4.翻转后4→3→2→1→5→6. 假设节点的数 ...

  6. [Ramda] Pick and Omit Properties from Objects Using Ramda

    Sometimes you just need a subset of an object. In this lesson, we'll cover how you can accomplish th ...

  7. js实现表格配对小游戏

    js实现表格配对小游戏 一.总结 一句话总结: 二.js实现表格配对 1.配对游戏案例说明 实例描述: 当用户点击两个相同的图案或字符后配对成功,全部配对成功后游戏获胜 案例008采用了大家常见的小游 ...

  8. java中的方法返回值使用泛型,实现灵活的返回值类型

    痛点:      使用Mybatis框架的时候,想封装一个底层JDBC控制器,用于提供和Mybatis交互的增删改查接口(公用的接口),但由于公用的查询方法可能是用户自定义的任意一个和表对应的java ...

  9. 一起学Python:列表介绍

    列表介绍 想一想: 前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢? 定义100个变量,每个变量存放一个学生的姓名可行吗?有更好的办法吗? 答: 列表 <1&g ...

  10. <meta http-equiv="refresh" content="0; url=">什么意思?

    原文:<meta http-equiv="refresh" content="0; url=">什么意思? 页面定期刷新,如果加url的,则会重新定 ...