前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BeautifulSoup文档4-详细方法 | 用什么方法对文档树进行搜索?

BeautifulSoup文档4-详细方法 | 用什么方法对文档树进行搜索?

原创
作者头像
虫无涯
发布2023-02-22 09:13:47
9140
发布2023-02-22 09:13:47
举报
文章被收录于专栏:全栈测试技术全栈测试技术
  • 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

  • True 可以匹配任何值;
  • 如查找到所有的tag
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参数

  • 查找所有名字为 nametag
  • 如: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>
...
  • 不使用recursive 参数:
print(soup.html.find_all("title"))
  • 输出为:
[<title>The Dormouse's story</title>]
  • 使用recursive 参数:
print(soup.html.find_all("title", recursive=False))
  • 输出为:
[]

3 find()

  • find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果;find( name , attrs , recursive , string , **kwargs )
  • find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None
  • 如:print(soup.find("nosuchtag")),输出为:None
  • 参数原型:

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 本文涉及的源码

# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2023/2/17 
# 文件名称:bs04.py
# 作用:beautifulsoup的应用
# 联系:VX(NoamaNelson)
# 博客:https://blog.csdn.net/NoamaNelson

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"]))
# True
for tag in soup.find_all(True):
    print(tag.name)

# ====== find_all() ======
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))

# ====== find() ======
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"))

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 过滤器
    • 1.1 字符串
      • 1.2 正则表达式
        • 1.3 列表
          • 1.4 True
            • 1.5 可以自定义方法
            • 2 find_all()
              • 2.1 参数原型
                • 2.2 name参数
                  • 2.3 keyword 参数
                    • 2.4 string 参数
                      • 2.5 limit 参数
                        • 2.6 recursive 参数
                        • 3 find()
                        • 4 find_parents()和find_parent()
                        • 5 find_next_siblings() 和 find_next_sibling()
                        • 6 find_previous_siblings() 和 find_previous_sibling()
                        • 7 find_all_next() 和 find_next()
                        • 8 find_all_previous() 和 find_previous()
                        • 9 本文涉及的源码
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档