读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() { ... }, ...
随机推荐
- winscp ppk无需密码登录(失败)
http://blog.csdn.net/catoop/article/details/8284803 按上文将Linux下生成的密钥文件id_rsa通过puttygen生成对应的.ppk文件,用wi ...
- .NET-架构优化实战-底层服务优化
原文:.NET-架构优化实战-底层服务优化 前言 问题分析 在本系列第一篇文章我们提到,底层问题主要存在以下两点: 代码冗余 时效低 代码冗余 例如: 领奖方法不统一,一次性的写一套,可循环的又写一套 ...
- winxp下安装mysql5.7提示mysqld.exe不是有效的win32文件
http://bbs.csdn.net/topics/391919244 http://haohaoxuexi.iteye.com/blog/2123030
- python3 numpy API练习代码
# -*- coding: utf-8 -*- import numpy as np; a=np.array([1,2,3,4,5,6]); print("数组是:",a) #数组 ...
- 【t096】树的序号
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 我们可以用下面的方案给二叉树标号: 空树的序号为0. 只有一个根结点的树序号为1. 所有包含m个结点的 ...
- p2p-如何拯救k8s镜像分发的阿喀琉斯之踵
K8s的出现为PaaS行业的发展打了一针兴奋剂,Docker+k8s的技术路线已经成为了容器云的主流.尤其针对大流量,大弹性的应用场景来说,k8s将其从繁杂的运维.部署工作中彻底拯救出来.然而事情往往 ...
- EasyUI入门:怎样引入及简单使用
或许,仅仅有当做比較大的项目的时候,才会发现封装好的东西会为程序员们带来多少方便.合作开发的时候更应该强调复用,才干更加发挥团队的优势. 今天使用了一些EasyUI,发现非常wonderful! 比方 ...
- vue sourcemap详解
从webpack开始 直接进入正题.有人觉得vue项目难调试,是因为用了webpack.所有代码揉在了一起,还加了很多框架代码,根本不知道怎么下手.所以vue+webpack调试要从webpack入手 ...
- iOS的安全性和越狱
提到越狱,很多人第一反应大概是免费的游戏和 app. 作为软件从业人员,深知中国的大环境的特殊性.内有用户想吃免费午餐的不良付费习惯,外有行业内大头诸如某讯对创新的绞杀.大家对越狱是为了免费.盗版软件 ...
- exponential family distribution(指数族分布)
1. exponential family 给定参数 η,关于 x 的指数族分布定义为如下的形式: p(x∣∣η)=h(x)g(η)exp{ηTu(x)} 其中 x 可以为标量也可以为矢量,可以为离散 ...