BeautifulSoup
的文档搜索方法有很多,官方文档中重点介绍了两个方法:
find() 和 find_all()
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser' )
1 过滤器
1.1 字符串
即在搜索方法中传如一个字符串参数; BeautifulSoup
会查找与字符串完全匹配的内容;如查找b
标签:
print (soup.find_all('b' ))
[<b>The Dormouse's story</b>]
1.2 正则表达式
传入正则表达式作为参数; Beautiful Soup
会通过正则表达式的 match()
来匹配内容;如找出所有以b
开头的标签:
import re
for tag in soup.find_all(re.compile ("^b" )):
print (tag.name)
body
b
1.3 列表
传入列表参数; Beautiful Soup
会将与列表中任一元素匹配的内容返回;如找到文档中所有a
标签和b
标签:
print (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>]
1.4 True
for tag in soup.find_all(True ):
print (tag.name)
html
head
title
body
p
b
p
a
a
a
p
1.5 可以自定义方法
如果没有合适过滤器,那么还可以定义一个方法; 方法只接受一个元素参数; 如果这个方法返回 True
表示当前元素匹配并且被找到,如果不是则反回 False
;
2 find_all()
搜索当前tag
的所有tag
子节点,并判断是否符合过滤器的条件。 比如:
print (soup.find_all("title" ))
[<title>The Dormouse's story</title>]
2.1 参数原型
find_all( name , attrs , recursive , string , **kwargs )
2.2 name参数
查找所有名字为 name
的tag
; 如:print(soup.find_all("title"))
,输出为:[<title>The Dormouse's story</title>]
。
2.3 keyword 参数
如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag
的属性来搜索; 如:print(soup.find_all(id='link2'))
,输出为:
[<a class ="sister" href="http://example.com/lacie" id ="link2" >Lacie</a>]
按照CSS
搜索,可以通过 class_
参数搜索有指定CSS
类名的tag
; 如:print(soup.find_all("a", class_="sister"))
,输出为:
[<a class ="sister" href="http://example.com/lacie" id ="link2" >Lacie</a>]
[<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>]
2.4 string 参数
通过 string
参数可以搜文档中的字符串内容.
与 name
参数的可选值一样; 如:print(soup.find_all(string="Elsie"))
,输出为:['Elsie']
;
2.5 limit 参数
可以使用 limit
参数限制搜索返回结果的数量,避免返回结果很大速度很慢; 如:soup.find_all("a", limit=2)
,输出为:
[<a class ="sister" href="http://example.com/elsie" id ="link1" >Elsie</a>,
<a class ="sister" href="http://example.com/lacie" id ="link2" >Lacie</a>]
2.6 recursive 参数
只搜索tag
的直接子节点,可以使用参数 recursive=False
; 如:
<html>
<head>
<title>
The Dormouse's story
</title>
</head>
...
print (soup.html.find_all("title" ))
[<title>The Dormouse's story</title>]
print (soup.html.find_all("title" , recursive=False ))
[]
3 find()
find_all()
方法的返回结果是值包含一个元素的列表,而 find()
方法直接返回结果;find_all()
方法没有找到目标是返回空列表, find()
方法找不到目标时,返回 None
。如:print(soup.find("nosuchtag"))
,输出为:None
。 参数原型:
find( name , attrs , recursive , string , **kwargs )
4 find_parents()和find_parent()
find_parents( name , attrs , recursive , string , **kwargs )
find_parent( name , attrs , recursive , string , **kwargs )
find_parents() 和 find_parent()
用来搜索当前节点的父辈节点;find_all() 和 find()
只搜索当前节点的所有子节点,孙子节点等;如:
a_string = soup.find(string="Lacie" )
print (a_string)
print (a_string.find_parents("a" ))
Lacie
[<a class ="sister" href="http://example.com/lacie" id ="link2" >Lacie</a>]
5 find_next_siblings() 和 find_next_sibling()
find_next_siblings( name , attrs , recursive , string , **kwargs )
find_next_sibling( name , attrs , recursive , string , **kwargs )
这2个方法通过 .next_siblings
属性对当tag
的所有后面解析的兄弟tag
节点进行迭代; find_next_siblings()
方法返回所有符合条件的后面的兄弟节点;find_next_sibling()
只返回符合条件的后面的第一个tag
节点;如:
first_link = soup.a
print (first_link)
print (first_link.find_next_siblings("a" ))
first_story_paragraph = soup.find("p" , "story" )
print (first_story_paragraph.find_next_sibling("p" ))
<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>]
<p class ="story" >...</p>
6 find_previous_siblings() 和 find_previous_sibling()
find_previous_siblings( name , attrs , recursive , string , **kwargs )
find_previous_sibling( name , attrs , recursive , string , **kwargs )
这2个方法通过 .previous_siblings
属性对当前tag
的前面解析的兄弟tag
节点进行迭代; find_previous_siblings()
方法返回所有符合条件的前面的兄弟节点;find_previous_sibling()
方法返回第一个符合条件的前面的兄弟节点。
7 find_all_next() 和 find_next()
find_all_next( name , attrs , recursive , string , **kwargs )
find_next( name , attrs , recursive , string , **kwargs )
这2个方法通过 .next_elements
属性对当前tag的之后的tag
和字符串进行迭代; find_all_next()
方法返回所有符合条件的节点;find_next()
方法返回第一个符合条件的节点。
8 find_all_previous() 和 find_previous()
find_all_previous( name , attrs , recursive , string , **kwargs )
find_previous( name , attrs , recursive , string , **kwargs )
这2个方法通过 .previous_elements
属性对当前节点前面的tag
和字符串进行迭代; find_all_previous()
方法返回所有符合条件的节点;find_previous()
方法返回第一个符合条件的节点。
9 本文涉及的源码
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser' )
print (soup.find_all('b' ))
import re
for tag in soup.find_all(re.compile ("^b" )):
print (tag.name)
print (soup.find_all(["a" , "b" ]))
for tag in soup.find_all(True ):
print (tag.name)
print (soup.find_all("title" ))
print (soup.find_all(id ='link2' ))
print (soup.find_all("a" , class_="sister" ))
print (soup.find_all(string="Elsie" ))
print (soup.find_all("a" , limit=2 ))
print (soup.html.find_all("title" , recursive=False ))
print (soup.find("nosuchtag" ))
a_string = soup.find(string="Lacie" )
print (a_string)
print (a_string.find_parents("a" ))
first_link = soup.a
print (first_link)
print (first_link.find_next_siblings("a" ))
first_story_paragraph = soup.find("p" , "story" )
print (first_story_paragraph.find_next_sibling("p" ))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧