通过操作方法进行解读搜索
实际上,网页中有用的信息都存在于网页中的文本或者各种不同标签的属性值,为了能获得这些有用的网页信息,可以通过一些查找方法获取文本或者标签属性。因此, bs4库内置了一些查找方法,其中常用的两个方法功能如下:
find()方法:用于查找符合查询条件的第一个标签节点;
find_all()方法:查找所有符合查询条件的标签节点,并返回一个列表。
这两个方法用到的参数是一样的,这里,我们以find_all()方法为例,介绍在这个方法中这些参数的使用。find_all()方法的定义如下:
find_all(self, name=None, attrs={}, recursive=True, text=None,
limit=None, **kwargs)
上述方法中一些重要参数所表示的含义如下:
1. name参数
查找所有名字为name的标签,不过字符串会被自动忽略掉。下面是name参数的几种情况:
- 传入字符串
在搜索的方法中传入一个字符串,BeautifulSoup对象会查找与字符串完全匹配的内容,具体示例如下:
soup.find_all('b')
上述示例用于查找文档中所有的< b>标签。
- 传入正则表达式
如果传入一个正则表达式,那么BeautifulSoup对象会通过re模块的match()函数进行匹配。下面的示例中,使用正则表达式“^b”匹配所有以字母b开头的标签,具体如下。
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
# 输出结果如下
body
- 传入列表
如果传入一个列表,那么BeautifulSoup对象会将与列表中任一元素匹配的内容进行返回。在下面的示例中,找到了文档中所有的< a>标签和< b>标签,具体如下。
soup.find_all(["a", "b"])
# 部分输出结果如下
[<b>The Dormouse's story</b>,
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
2. keyword参数
如果某个指定名字的参数不是搜索方法中内置的参数名,那么在进行搜索时,会把该参数当作指定名称的标签中的属性来搜索。在下面的示例中,在find_all()方法中传入名称为id的参数,这时BeautifulSoup对象会搜索每个标签的id属性,具体如下。
soup.find_all(id='link2')
# 输出的结果可能是:
[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
若传入多个指定名字的参数,则可以同时过滤出标签中的多个属性。在下面的示例中,既可以搜索每个标签的id属性,同时又可以搜索href属性,具体如下。
import re
soup.find_all(href=re.compile("elsie"), id='link1')
# 输出的结果可能是:
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
如果要搜索的标签名称为class,由于class属于Python的关键字,所以可以在class的后面加上一个下划线,示例如下。
soup.find_all("a", class_="sister")
# 部分输出结果如下:
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
不过,有些标签的属性名称是不能使用的,比如HTML5中的“data-”属性。在程序中使用时,会出现SyntaxError异常信息。这时,可以通过find_all()方法的attrs参数传入一个字典来搜索包含特殊属性的标签,具体示例代码如下。
data_soup = BeautifulSoup('<div data-foo="value">foo!</div>' ,'lxml')
data_soup.find_all(data-foo="value")
# 程序输出如下报错信息:
# SyntaxError: keyword can't be an expression
data_soup.find_all(attrs={"data-foo": "value"})
# 程序可匹配的结果
# [<div data-foo="value">foo!</div>]
3. text参数
通过在find_all()方法中传入text参数,可以搜索文档中的字符串内容。跟name参数的可选值一样,text参数也可以接受字符串、正则表达式和列表等,具体示例代码如下。
soup.find_all(text="Elsie")
# [u'Elsie']
soup.find_all(text=["Tillie", "Elsie", "Lacie"])
# [u'Elsie', u'Lacie', u'Tillie']
4. limit 参数
在使用find_all()方法返回匹配的结构时,倘若DOM树非常大,那么搜索的速度会相当慢。这时,如果不需要获得全部的结果,就可以使用limit参数限制返回结果的数量,其效果跟SQL语句中的limit关键字所产生的效果类似。一旦搜索到结果的数量达到了limit的限制时,就会停止搜索,示例代码如下。
soup.find_all("a", limit=2)
上述示例会搜索到至多两个符合搜索条件的标签。
5. recursive参数
在调用find_all() 方法时,BeautifulSoup对象会检索当前节点的所有子孙节点。这时,如果只想搜索当前节点的直接子节点,那么就可以使用参数recursive=False,具体示例代码如下。
soup.html.find_all("title")
# [<title>The Dormouse's story</title>]
soup.html.find_all("title", recursive=False)
# []
除了上述两个常用的方法以外,bs4库中还提供了一些通过节点间的关系进行查找的方法。由于这些方法的参数和用法跟find_all()方法类似,这里就不再另行介绍了,大家可以举一反三。