【问题标题】:Parsing Poorly Formed HTML/XML-ish Content解析格式不佳的 HTML/XML-ish 内容
【发布时间】:2015-02-16 16:16:08
【问题描述】:

我需要解析来自我完全无法控制的远程服务器的内容,返回类似于此的内容:

<alpha>
<bravo>123
<charlie>Some
Multiline
Text
</alpha>

<alpha>
<bravo>456
<charlie>More text
</alpha>

BeautifulSoup 通过将其解释为解析标记做了一项有趣的工作:

<html>
    <body>
        <alpha>
        <bravo>123
        <charlie>Some
        Multiline
        Text</charlie></bravo>
        </alpha>

        <alpha>
        <bravo>456
        <charlie>More text</charlie></bravo>
        </alpha>
    </body>
</html>

虽然我想要类似的东西:

<html>
    <body>
        <alpha>
        <bravo>123</bravo>
        <charlie>Some
        Multiline
        Text</charlie>
        </alpha>

        <alpha>
        <bravo>456</bravo>
        <charlie>More text</charlie>
        </alpha>
    </body>
</html>

所以我将其解析为某种alphas 数组,其结构类似于:

[
    { bravo: ... , charlie: ... }
    { bravo: ... , charlie: ... }
]

我不能在下一个换行符之前读取每个节点的内容,因为内容有时会跨越多行。

有人知道我可以解析这个的方法吗?或推荐其他图书馆使用?

【问题讨论】:

  • 这么美的汤有什么问题?
  • @JoranBeasley 我无法将bravocharlie 值分开,因为它会嵌套它们以尝试修复标记

标签: python xml xml-parsing beautifulsoup html-parsing


【解决方案1】:

您需要在xml features turned on 中对其进行解析,以使其在后台使用lxml XML 解析器。

BeautifulSoup(data, "xml")

注意,这需要安装lxml 模块。

演示:

>>> from bs4 import BeautifulSoup
>>> 
>>> data = """
... <alpha>
... <bravo>123
... <charlie>Some
... Multiline
... Text
... </alpha>
... 
... <alpha>
... <bravo>456
... <charlie>More text
... </alpha>
... """
>>> soup = BeautifulSoup(data, "xml")
>>> print soup.prettify()
<?xml version="1.0" encoding="utf-8"?>
<alpha>
 <bravo>
  123
  <charlie>
   Some
Multiline
Text
  </charlie>
  <alpha>
   <bravo>
    456
    <charlie>
     More text
    </charlie>
   </bravo>
  </alpha>
 </bravo>
</alpha>

附带说明一下,运行 diagnose() 并查看不同的解析器如何解析您拥有的输入数据。


以下是获取所需词典列表的方法:

print [{'bravo': alpha.bravo.get_text(strip=True),
        'charlie': alpha.charlie.get_text(strip=True)}
       for alpha in soup('alpha')]

打印:

[
    {'bravo': u'123Some\nMultiline\nText456More text', 'charlie': u'Some\nMultiline\nText'}, 
    {'bravo': u'456More text', 'charlie': u'More text'}
]

【讨论】:

  • 首先,非常感谢您的详细回复,但我无法弄清楚如何只读取每个标签的内容而不包括以下所有标签的内容。我在我的 OP 中没有明确说明,在您的示例中,bravo 值仍然包括 charlie 值,我需要将它们分开,尽管服务器响应的标记很糟糕
  • @Greg 欢迎您。这是您每次从服务器获得的东西吗?换句话说,bravocharlie 总是没有结束标签吗?谢谢。
  • 据我所知,是的,每个对象都有完全相同的属性/子标签
  • @Greg 首先,正如您所看到的,您仍然可以获取字典列表中的值(即使在 BeautifulSoupalphas 内部嵌套了子项..)跨度>
  • @Greg 但是,是的,我们仍然可以在使用 BeautifulSoup 加载节点后重新排列节点 - 将 charlie 上移一级。
猜你喜欢
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 2016-11-20
  • 1970-01-01
  • 2014-02-05
相关资源
最近更新 更多