【问题标题】:How can I load an html file into a multilevel array of elements in python如何将html文件加载到python中的多级元素数组中
【发布时间】:2019-11-11 12:17:15
【问题描述】:

在理想情况下,我试图弄清楚如何将 html 文档加载到元素列表中,例如:

elements=[['h1', 'This is the first heading.'], ['p', 'Someone made a paragraph. A short one.'], ['table', ['tr', ['td', 'a table cell']]]]

我用 beautifulsoup 玩了一点,但没有办法做到这一点。

这目前可行吗,还是我需要编写解析器。

【问题讨论】:

    标签: python html


    【解决方案1】:

    在一个理想的世界中(定义:您想要阅读的网站具有格式良好的 XHTML),您可以将它扔给像 lxml 这样的 XML 解析器,您会得到类似的东西。非常简短的版本:

    • 元素是列表,列表中的条目是子元素,顺序正确
    • 元素是字典,具有元素的“key=value”属性。
    • 元素有一个文本属性,它是开始元素和它的第一个子元素之间的文本
    • 元素有一个tail属性,即结束元素之后的文本。

    一旦你有了这样形状的树,你就可以编写一个 3 行函数,按照你想要的方式重建它。


    XHTML 基本上是受限制的 HTML——它与 XML 的结合。 理论上,网站应该为您的浏览器提供 XHTML,因为它在各方面都更好,但大多数浏览器都更加宽松,因此不提供更严格的设置。

    大多数网站都存在一些问题,例如省略结束标签。 XML 解析器往往会在这些问题上出错。

    【讨论】:

      【解决方案2】:

      你可以使用递归:

      html = """
      <html>
        <body>
           <h1>This is the first heading.</h1>
           <p>Someone made a paragraph. A short one.</p>
           <table>
             <tr>
               <td>a table cell</td>
             <tr>
           </table>
        </body>
      </html>
      """
      import bs4
      def to_list(d):
         return [d.name, *[to_list(i) if not isinstance(i, bs4.element.NavigableString) else i for i in d.contents if i != '\n']]
      
      _, *r = to_list(bs4.BeautifulSoup(html).body)
      print(r)
      

      输出:

      [['h1', 'This is the first heading.'], ['p', 'Someone made a paragraph. A short one.'], ['table', ['tr', ['td', 'a table cell'], ['tr']]]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-19
        • 2017-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多