如何使用 bs4 或 lxml 在 Python 中找到 XML 标记的文本行?

Posted

技术标签:

【中文标题】如何使用 bs4 或 lxml 在 Python 中找到 XML 标记的文本行?【英文标题】:How can I get the line of the text where an XML tag is found in Python using bs4 or lxml? 【发布时间】:2021-04-06 08:25:17 【问题描述】:

我有一个 XML 文档,我想获取找到 BeautifulSouplxml 提取的标记所在的行。有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

对于 BeautifulSoup,此属性存储在 Tag 类的 sourceline attribute 中,并在解析器 here 和 here 中填充。

对于 lxml,这也可以通过 sourceline 属性实现。这是一个例子:

#!/usr/bin/python3
from lxml import etree
xml = '''
<a>
  <b>
    <c>
    </c>
  </b>
  <d>
  </d>
</a>
'''
root = etree.fromstring(xml)

for e in root.iter():
    print(e.tag, e.sourceline)

输出:

a 2
b 3
c 4
d 7

如果您想查看sourceline method 的实现,它实际上是在调用xmlGetLineNo,它是来自libxml2 的xmlGetLineNo 的绑定,它是xmlGetLineNoInternal 的包装器(其中的实际逻辑位于libxml2 中)。

您也可以find the line number of the closing tag 检查该标记的子树的文本表示中有多少行结尾。

xml.etree.ElementTree 可以also be extended 提供解析器找到元素所在的行号(解析器是来自模块xml.parsers.expat 的xmlparser)。

【讨论】:

【参考方案2】:

尝试使用enumerate() 函数。

例如,如果我们有以下 html

html = """
<!DOCTYPE html>
<html>
<body>
<h1>My Heading</h1>
<p>My paragraph.</p>
</body>
</html>"""

我们希望找到&lt;h1&gt; 标记的行号 (&lt;h1&gt;My Heading&lt;/h1&gt;)。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")

for (index, value) in enumerate(
    # Remove all the empty lines, so that they shouldn't be part of the line count
    (x for x in str(soup).splitlines() if x != ""),
    start=1,
):
    # Specify the tag you want to find
    # If the tag is found, it will return `1`, else `-1`
    if value.find("h1") == 1:
        print(f"Line: index.\t Found: 'value' ")
        break

输出:

Line: 4.     Found: '<h1>My Heading</h1>' 

【讨论】:

以上是关于如何使用 bs4 或 lxml 在 Python 中找到 XML 标记的文本行?的主要内容,如果未能解决你的问题,请参考以下文章

bs4.FeatureNotFound: ... lxml 与 MacOS 和 Conda / Python 3

Python spider Requests && Lxml && bs4

Python spider Requests && Lxml && bs4

如何使用 BS4 和 LXML 获取 xpath

如何重新安装lxml?

如何重新安装lxml?