【问题标题】:How to convert an HTML table to an array in python如何在python中将HTML表格转换为数组
【发布时间】:2011-02-21 16:13:30
【问题描述】:

我有一个 html 文档,我想从该文档中提取表格并将它们作为数组返回。我正在描绘 2 个函数,一个用于查找文档中的所有 html 表格,另一个用于将 html 表格转换为二维数组。

类似这样的:

htmltables = get_tables(htmldocument)
for table in htmltables:
    array=make_array(table)

有 2 个问题: 1. 数字表每天都在变化 2.表格有各种奇怪的额外格式,比如粗体和闪烁标签,随机扔进去。

谢谢!

【问题讨论】:

    标签: python html


    【解决方案1】:

    使用BeautifulSoup(我推荐3.0.8)。查找所有表很简单:

    import BeautifulSoup
    
    def get_tables(htmldoc):
        soup = BeautifulSoup.BeautifulSoup(htmldoc)
        return soup.findAll('table')
    

    但是,在 Python 中,array 是一维的,并且仅限于作为项目的基本类型(整数、浮点数、 基本类型)。所以没有办法在 Python array 中压缩 HTML 表格。

    也许您的意思是 Python list?这也是一维的,但任何东西都可以是一个项目,所以你可以有一个列表列表(我想每个 tr 标签一个子列表,每个 td 标签包含一个项目)。

    这会给出:

    def makelist(table):
      result = []
      allrows = table.findAll('tr')
      for row in allrows:
        result.append([])
        allcols = row.findAll('td')
        for col in allcols:
          thestrings = [unicode(s) for s in col.findAll(text=True)]
          thetext = ''.join(thestrings)
          result[-1].append(thetext)
      return result
    

    这可能还不是你想要的(不跳过 HTML cmets,子列表的项目是 unicode 字符串而不是字节字符串等),但它应该很容易调整。

    【讨论】:

    • 美汤既好喝又简单!如果需要更快的速度,也可以尝试使用 lxml+xpath。
    • @user,总是乐于提供帮助。如果它对您的问题的回答非常好,您应该“接受”它(通过单击答案左上角投票数下方的复选标记形图标)——这是 SO 礼仪的关键部分!-)
    • 还有一个问题:如果表格有标题行怎么办?
    • 这将有th 项目而不是td,因此result 中的相应子列表将为空——您可以在for col 循环之后添加if not result[-1]: del result[-1] 以删除此类例如,空行。
    • 如果我想在列表中包含这些标题行怎么办?
    【解决方案2】:

    Pandas 可以直接将 html 中的所有表格提取到数据框列表中,从而使您不必自己解析页面(重新发明轮子)。 DataFrame 是一种强大的二维数组。

    我建议继续通过 Pandas 处理数据,因为它是一个很棒的工具,但如果您愿意,也可以转换为其他格式(列表、字典、csv 文件等)。

    示例

    """Extract all tables from an html file, printing and saving each to csv file."""
    
    import pandas as pd
    
    df_list = pd.read_html('my_file.html')
    
    for i, df in enumerate(df_list):
        print df
        df.to_csv('table {}.csv'.format(i))
    

    直接从网络而不是从文件中获取 html 内容只需要稍作修改:

    import requests
    
    html = requests.get('my_url').content
    df_list = pd.read_html(html)
    

    【讨论】:

      【解决方案3】:

      向提问者 +1,向 Python 之神 +1。
      想使用 lxml 和 CSS 选择器尝试这个示例。
      是的,这与 Alex 的示例大体相同:

      import lxml.html
      markup = lxml.html.fromstring('''<html><body>\
      <table width="600">
          <tr>
              <td width="50%">0,0,0</td>
              <td width="50%">0,0,1</td>
          </tr>
          <tr>
              <td>0,1,0</td>
              <td>0,1,1</td>
          </tr>
      </table>
      <table>
          <tr>
              <td>1,0,0</td>
              <td>1,<blink>0,</blink>1</td>
              <td>1,0,2</td>
              <td><bold>1</bold>,0,3</td>
          </tr>
      </table>
      </body></html>''')
      
      tbl = []
      rows = markup.cssselect("tr")
      for row in rows:
        tbl.append(list())
        for td in row.cssselect("td"):
          tbl[-1].append(unicode(td.text_content()))
      
      pprint(tbl)
      #[[u'0,0,0', u'0,0,1'],
      # [u'0,1,0', u'0,1,1'],
      # [u'1,0,0', u'1,0,1', u'1,0,2', u'1,0,3']]
      

      【讨论】:

      • 使用list() 而不是普通的[] 很奇怪。
      • @J.F.是的,我想是的。感谢您的评论,以及您所有出色的答案 :-) 继续努力。
      猜你喜欢
      • 2011-05-30
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 2019-06-13
      • 2015-10-30
      相关资源
      最近更新 更多