BeautifulSoup find_all()用于查找具有多个可接受属性值之一的元素

时间:2014-09-14 06:20:17

标签: python python-3.x beautifulsoup

主要问题

我知道如何使用find_all()来检索具有特定值属性的元素,但是我找不到任何有关如何检索具有多个可接受值之一的属性的元素的示例。在我的情况下,我正在使用DITA XML,我想检索其中scope属性是以下之一的topicref元素:

  • “对等”
  • “本地”
  • 无(该属性不存在)

我写了一个有效的自定义函数,但必须有一个更聪明的方法来使用BeautifulSoup中已经存在的函数。这是我的代码:

from bs4 import BeautifulSoup

with open("./dita_source/envvariables.ditamap","r") as file:
    doc = BeautifulSoup(file)
    file.close()


def isLocal(element):
    if (element.name == "topicref"):
        if (not element.has_attr("scope") or element["scope"] == "local" or element["scope"] == "peer"):
            return True;
    return False;

topicrefs = doc.find_all(isLocal)

次要问题

有没有办法将find_all()与其标准过滤器以及自定义函数一起使用?我试过了doc.find_all("topicref", isLocal),但那没用。我不得不将额外的if (element.name == "topicref"):语句添加到我的自定义函数中。

2 个答案:

答案 0 :(得分:1)

您可以将列表作为属性参数的值提供给find_all(),它将返回属性与该列表中的任何项匹配的元素:

>>> soup.find_all(scope=["row", "col"])
[
    <th scope="col">US $</th>,
    <th scope="col">Euro</th>,
    <th scope="row">Mon – Fri</th>,
    <th scope="row">Sat – Sun</th>,
]

...但是没有办法指定&#34;属性根本不存在&#34;在该列表中(None和空字符串都不起作用)。因此,您需要一个功能。

答案 1 :(得分:0)

指定topicref作为第一个参数(name)并传递scope关键字参数的函数:

def isLocal(scope):
    return scope in (None, "local", "peer")

topicrefs = soup.find_all('topicref', scope=isLocal)

或使用lambda

topicref = soup.find_all(
    'topicref',
    scope=lambda scope: scope in (None, "local", "peer")
)