测试beautifulsoup中是不是存在children标签

Posted

技术标签:

【中文标题】测试beautifulsoup中是不是存在children标签【英文标题】:Test if children tag exists in beautifulsoup测试beautifulsoup中是否存在children标签 【发布时间】:2016-01-19 04:44:32 【问题描述】:

我有一个具有已定义结构但标签数量不同的 XML 文件,例如

file1.xml:

<document>
  <subDoc>
    <id>1</id>
    <myId>1</myId>
  </subDoc>
</document>

file2.xml:

<document>
  <subDoc>
    <id>2</id>
  </subDoc>
</document>

现在我想检查一下标签myId 是否退出。所以我做了以下事情:

data = open("file1.xml",'r').read()
xml = BeautifulSoup(data)

hasAttrBs = xml.document.subdoc.has_attr('myID')
hasAttrPy = hasattr(xml.document.subdoc,'myID')
hasType = type(xml.document.subdoc.myid)

结果是 文件 1.xml:

hasAttrBs -> False
hasAttrPy -> True
hasType ->   <class 'bs4.element.Tag'>

file2.xml:

hasAttrBs -> False
hasAttrPy -> True
hasType -> <type 'NoneType'>

好的,&lt;myId&gt; 不是&lt;subdoc&gt; 的属性。

但是如果存在子标签,我该如何测试呢?

//编辑:顺便说一句:我不太喜欢遍历整个子文档,因为那样会很慢。我希望找到一种方法可以直接解决/询问该元素。

【问题讨论】:

【参考方案1】:

你可以这样处理:

for child in xml.document.subdoc.children:
    if 'myId' == child.name:
       return True

【讨论】:

谢谢。但是:我的想法是,我真的不喜欢遍历整个子文档,因为这些文档很大,我必须遍历数千个 xml 文件。我希望找到一种方法可以直接解决/询问该元素。【参考方案2】:

查找子标签是否存在的最简单方法就是

childTag = xml.find('childTag')
if childTag:
    # do stuff

更具体地说是 OP 的问题:

如果你不知道XML doc的结构,可以使用soup的.find()方法。像这样的:

with open("file1.xml",'r') as data, open("file2.xml",'r') as data2:
    xml = BeautifulSoup(data.read())
    xml2 = BeautifulSoup(data2.read())

    hasAttrBs = xml.find("myId")
    hasAttrBs2 = xml2.find("myId")

如果您知道结构,则可以通过访问标记名称作为属性来获取所需的元素,例如xml.document.subdoc.myid。所以整个事情会是这样的:

with open("file1.xml",'r') as data, open("file2.xml",'r') as data2:
    xml = BeautifulSoup(data.read())
    xml2 = BeautifulSoup(data2.read())

    hasAttrBs = xml.document.subdoc.myid
    hasAttrBs2 = xml2.document.subdoc.myid
    print hasAttrBs
    print hasAttrBs2

打印

<myid>1</myid>
None

【讨论】:

...但是find() 在文档中搜索,对吗?但是,我知道标签洞察 xml 树的位置(如果存在)。那么有没有简单的方法可以直接寻址一个元素或检查该元素是否存在? 哦,好吧,很抱歉我第一次误解了。我已经更新了我的答案。 哦,我明白了....“保持简单”有时是最好的方法。谢谢你打开我的眼睛...【参考方案3】:
if tag.find('child_tag_name'):

【讨论】:

【参考方案4】:

这是一个检查 h2 标签是否存在于 Instagram URL 中的示例。希望对您有用:

import datetime
import urllib
import requests
from bs4 import BeautifulSoup

instagram_url = 'https://www.instagram.com/p/BHijrYFgX2v/?taken-by=findingmero'
html_source = requests.get(instagram_url).text
soup = BeautifulSoup(html_source, "lxml")

if not soup.find('h2'):
    print("didn't find h2")

【讨论】:

这一行就在这里“如果不是soup.find('h2'):”只是让我头疼不已。我不知道这件事。谢谢! 在 bs4 标签内,使用 has_attr(key) 代替,如 alt_image_text = [tag["alt"] for tag in images if tag.has_attr("alt")]。请注意,tag.src 似乎总是返回 None。【参考方案5】:

你可以用if tag.myID:做到这一点

如果您想检查myID 是否是直接子代而不是子代的子代,请使用if tag.find("myID", recursive=False):

如果要检查标签是否没有子标签,请使用if tag.find(True):

【讨论】:

【参考方案6】:
page = requests.get("http://dataquestio.github.io/web-scraping-pages/simple.html")
page
soup = BeautifulSoup(page.content, 'html.parser')
testNode = list(soup.children)[1]

def hasChild(node):
    print(type(node))
    try:
        node.children
        return True
    except:
        return False

 if( hasChild(testNode) ):
     firstChild=list(testNode.children)[0]
     if( hasChild(firstChild) ):
        print('I found Grand Child ')

【讨论】:

【参考方案7】:

如果您使用的是 CSS 选择器

content = soup_elm.select('.css_selector')
if len(content) == 0:
    return None

【讨论】:

以上是关于测试beautifulsoup中是不是存在children标签的主要内容,如果未能解决你的问题,请参考以下文章

如果标签存在,beautifulsoup 从片段中获取最后一个标签

BeautifulSoup 中是不是有 InnerText 等价物?

如何识别beautifulsoup返回的'p'标签中是否存在'span'子标签?

Beautifulsoup 的“单元测试失败”

Beautifulsoup关于find的测试

beautifulsoup测试