【问题标题】:Python solution to convert HTML tables to readable plain text将 HTML 表格转换为可读纯文本的 Python 解决方案
【发布时间】:2013-05-20 20:54:17
【问题描述】:

我正在寻找一种将 HTML 表格干净地转换为可读纯文本的方法。

即给定一个输入:

<table>
    <tr>
        <td>Height:</td>
        <td>200</td>
    </tr>
    <tr>
        <td>Width:</td>
        <td>440</td>
    </tr>
</table>

我期望输出:

Height: 200
Width: 440

我宁愿不使用外部工具,例如w3m -dump file.html,因为它们 (1) 依赖于平台,(2) 我想对流程进行一些控制,并且 (3) 我认为它可以单独使用 Python,无论是否有额外的模块。

我不需要任何自动换行或可调整的单元格分隔符宽度。将制表符用作单元格分隔符就足够了。

更新

这是一个老用例的老问题。鉴于pandas provides the read_html method,我目前的答案肯定是pandas-based

【问题讨论】:

    标签: python html html-table html-parsing plaintext


    【解决方案1】:

    用这个怎么样:

    Parse HTML table to Python list?

    但是,使用collections.OrderedDict() 而不是简单的字典来保持顺序。有了字典后,就可以非常非常容易地从中获取文本并设置其格式:

    使用@Colt 45 的解决方案:

    import xml.etree.ElementTree
    import collections
    
    s = """\
    <table>
        <tr>
            <th>Height</th>
            <th>Width</th>
            <th>Depth</th>
        </tr>
        <tr>
            <td>10</td>
            <td>12</td>
            <td>5</td>
        </tr>
        <tr>
            <td>0</td>
            <td>3</td>
            <td>678</td>
        </tr>
        <tr>
            <td>5</td>
            <td>3</td>
            <td>4</td>
        </tr>
    </table>
    """
    
    table = xml.etree.ElementTree.XML(s)
    rows = iter(table)
    headers = [col.text for col in next(rows)]
    for row in rows:
        values = [col.text for col in row]
        for key, value in collections.OrderedDict(zip(headers, values)).iteritems():
            print key, value
    

    输出:

    Height 10
    Width 12
    Depth 5
    Height 0
    Width 3
    Depth 678
    Height 5
    Width 3
    Depth 4
    

    【讨论】:

    • 谢谢你的示例代码,但问题是它只处理一种特殊情况,我的实际输入有点复杂,并且包含很多 colspan,所以它不会以我想要的方式显示数据到。这是实际数据的示例:pastebin.com/yRQvz2Ww 目前我尝试的所有选项(elementree、lxml、BeautifulSoup)都没有接近w3m -dump 的输出和我的输入。
    • 这是一个完全不同的问题——我的意思是给定的输入预期的输出不是你问的。对于您首先提出的问题,我的回答是有效的。
    • 我原来的例子是generic,理想的答案也是generic。您提出的解决方案确实解决了最简单的情况,但还不够通用
    【解决方案2】:

    您应该查看标准库模块 ElementTreeminidom

    【讨论】:

      【解决方案3】:

      您可以在http://htql.net 使用 HTQL 模块。

      这是您页面的示例代码:

      import urllib2
      url='http://pastebin.com/yRQvz2Ww'
      page=urllib2.urlopen(url).read();
      
      query="""<div (ID='super_frame')>1.<div (ID='monster_frame')>1.<div (ID='content_frame')>1.<div (ID='content_left')>1.<div (ID='code_frame2')>1.<div (ID='code_frame')>1.<div (ID='selectable')>1.<div (CLASS='html4strict')>1 &tx
      <table>.<tr>{
          c1=<td>:colspan;   t1=<td>1 &tx; 
          c2=<td>2:colspan;   t2=<td>2 &tx;
          c3=<td>3:colspan;   t3=<td>3 &tx; 
          c4=<td>4:colspan;   t4=<td>4 &tx;
          c5=<td>5:colspan;   t5=<td>5 &tx;
      }
      """
      
      for t in htql.query(page, query): 
          print('\t'.join(t)); 
      

      htql.query() 产生 10 列,包括 c1, t2, c2, t2, ... c5, t5。您可以使用 c1..c5 信息来了解 t1..t5 应该在哪些单元格中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-22
        • 1970-01-01
        • 1970-01-01
        • 2012-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多