【问题标题】:BeautifulSoup counting tags without parsing deep inside themBeautifulSoup 计数标签而不深入解析它们
【发布时间】:2015-02-24 17:46:32
【问题描述】:

我想到了以下while writing an answer to this question

假设我有一个像这样深度嵌套的 xml 文件(但嵌套更多且更长):

<section name="1">
    <subsection name"foo">
        <subsubsection name="bar">
            <deeper name="hey">
                <much_deeper name"yo">
                    <li>Some content</li>
                </much_deeper>
            </deeper>
        </subsubsection>
    </subsection>
</section>
<section name="2">
    ... and so forth
</section>

len(soup.find_all("section")) 的问题在于,在执行find_all("section") 时,BS 一直在深入搜索我知道不会包含任何其他 section 标记的标记。

那么,两个问题:

  1. 有没有办法让BS递归搜索到已经找到的标签?
  2. 如果对 1 的回答是肯定的,是效率更高还是内部流程相同?

【问题讨论】:

  • len(soup.find_all('section')) 为我显示 2。你有什么问题?
  • @AvinashRaj 确实是这样,但是soup.find_all('section') 在传递给len() 之前会带来巨大的开销。或者,根本没有开销,它只是一个传递引用的游戏。因此我的问题:)
  • 我认为没有其他方法了。 stackoverflow.com/questions/13853025/…
  • 也许你可以使用 regx。 len(re.findall(r'&lt;section\b[^&lt;&gt;]*&gt;', html))
  • 不相信正则表达式。还是)感谢你的建议。我想如果find_all是官方的计数方式,一定要为此优化。

标签: python xml xml-parsing beautifulsoup


【解决方案1】:

BeautifulSoup 不能只给你它找到的标签的计数/数量。

不过,您可以改进的是:不要让 BeautifulSoup 通过传递 recursive=False 在其他部分中搜索部分:

len(soup.find_all("section", recursive=False))

除了改进之外,lxml 会更快地完成这项工作:

tree.xpath('count(//section)')

【讨论】:

  • @AvinashRaj 抱歉,你这是什么意思?请详细说明。谢谢。
  • soup.find_all("section", recursive=False) 返回一个空列表。 len(soup.find_all("section", recursive=False)) 显示 0。
  • 正是我想要的。谢谢。是的,在这种情况下,我想直接调用lxml 会更快。您知道这种使用lxml 的特殊方式是进行完全递归搜索还是只是停留在“表面”?
  • @Jivan 我认为在这种情况下直接调用lxml 会更有效,因为即使lxml 递归地遍历整个树来计算section 的出现次数,它也是在C 中完成的这只是一个计数器,它不会像find_all() 那样创建携带孩子的Tag 实例。希望这是有道理的。谢谢。
  • @AvinashRaj 应该可以工作。我猜它对你不起作用,因为它需要为BeautifulSoup 打开xml 功能并具有单个根元素。例如。这对我有用:gist.github.com/alecxe/606a1983aabce8068257。感谢您对此进行调查。
猜你喜欢
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 2017-09-24
  • 2013-03-20
  • 2012-05-22
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
相关资源
最近更新 更多