【问题标题】:Efficient way to parse html when only need first occurrence of specific tag只需要第一次出现特定标签时解析 html 的有效方法
【发布时间】:2019-07-09 20:14:51
【问题描述】:

我有一个很大的 html 文档。我正在使用 BeautifulSoup 解析它,但我希望提取的唯一信息是特定标签的文本(我相信它只会出现一次)。

文档格式如下:

    <html>
        <div class=...>
            <div class=...
                <div class="foo">
    ...
    ...

目前,我正在使用 SoupStrainer 仅过滤具有“foo”类的 div 标签。 也许我应该使用不同的库,或者我误解了 SoupStrainer 在做什么。

    html = open("file.html", encoding="UTF8").read()
    parse_only = SoupStrainer("div", class_="foo")
    soup = BeautifulSoup(raw_html, "lxml", parse_only=parse_only)
    text = soup.text

我希望这会比没有 SoupStrainer 时快得多,但我只得到了大约 2 倍的加速,我希望它更快。我认为这样做的原因是它仍然需要检查文档中的每个标签是否匹配。我希望它简单地停在与该标签匹配的第一个标签上,而不再花时间解析文档。

【问题讨论】:

  • 如果您的解析任务如此简单,我建议您不要使用解析包。只需使用string.find()

标签: python beautifulsoup


【解决方案1】:

我建议您使用 lxml 库和 etree hack。 这就像逐个标签读取,而不是读取整个文件。这称为事件驱动解析。

请在此处查看更多信息https://lxml.de/tutorial.html#event-driven-parsing

这里有教程: http://boscoh.com/programming/reading-xml-serially.html 和这里: https://www.ibm.com/developerworks/xml/library/x-hiperfparse/

这些示例是针对 html 的,但您也可以使用 lxml 来解析 html。 我的情况是我有 1.1GB 文本 xml 文件,查看整个文件花了我大约 10m。

快速示例:

inputfile = open('file.html')
context = etree.iterparse(inputfile, events=('end',), tag='YOUR_TAG_NAME')

for event, elem in context:
    if event == END and elem.tag == 'YOUR_TAG_NAME':
        print(elem.text)

【讨论】:

  • 谢谢,这看起来很适合我的需要。
【解决方案2】:

Beautiful Soup 的find 功能应该可以帮到你。

html = open("file.html", encoding="UTF8").read()
soup = BeautifulSoup(html)
print(soup.find("div", class_="foo"))

这将只获取第一个匹配项。

【讨论】:

  • 对不起,我应该提到 - 这是我尝试的第一件事。问题是 BeautifulSoup 调用会解析整个文档,因此非常昂贵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2012-12-01
  • 1970-01-01
  • 2019-07-28
  • 2011-06-28
  • 1970-01-01
相关资源
最近更新 更多