【问题标题】:Transform HTML table to JSON将 HTML 表格转换为 JSON
【发布时间】:2013-07-02 07:12:43
【问题描述】:

我有一个巨大的 HTML 表(大约 500,000 行),我需要将其转换为 JSON 文件。 该表如下所示:

<table>
<tr>
<th>Id</th>
<th>Timestamp</th>
<th>Artist_Name</th>
<th>Tweet_Id</th>
<th>Created_at</th>
<th>Tweet</th>
<th>User_name</th>
<th>User_Id</th>
<th>Followers</th>
</tr>
<tr>
<td>1</td>
<td>2013-06-07 16:00:17</td>
<td>Kelly Rowland</td>
<td>343034567793442816</td>
<td>Fri Jun 07 15:59:48 +0000 2013</td>
<td>So has @MissJia already discussed this Kelly Rowland Dirty Laundry song? I ain't trying to go all through her timelime...</td>
<td>Nicole Barrett</td>
<td>33831594</td>
<td>62</td>
</tr>
<tr>
<td>2</td>
<td>2013-06-07 16:00:17</td>
<td>Kelly Rowland</td>
<td>343034476395368448</td>
<td>Fri Jun 07 15:59:27 +0000 2013</td>
<td>RT @UrbanBelleMag: While everyone waits for Kelly Rowland to name her abusive ex, don't hold your breath. But she does say he's changed: ht…</td>
<td>A.J.</td>
<td>24193447</td>
<td>340</td>
</tr>

我想创建一个看起来像这样的 JSON 文件:

{'data': [
  {
   'text': 'So has @MissJia already discussed this Kelly Rowland Dirty Laundry song? I ain't trying to go all through her timelime...', 
   'id': 1, 
   'tweet_id': 343034567793442816
  },
  {
   'text': 'RT @UrbanBelleMag: While everyone waits for Kelly Rowland to name her abusive ex, don't hold your breath. But she does say he's changed: ht…', 
   'id': 2, 
   'tweet_id': 343034476395368448
  }
]}

也许包含更多变量,但这应该是自我解释的。

我已经研究了几个选项,但大多数情况下我的 HTML 表太大了。我看到很多人推荐 jQuery。考虑到我的桌子的大小,这对我有意义吗? 如果有合适的 Python 选项,我会非常赞成,因为到目前为止我的大部分代码都是用 Python 编写的。

【问题讨论】:

  • 哇,一个有 500,000 行的 html 表格,伙计,这太大了,我会说太大了……为什么不使用分页呢?顺便说一句,这些数据从哪里来?我认为你没有硬编码你的表,对吧?!
  • 数据是从 Twitter 爬取的。我在数据库中有它,但到目前为止导出只在 HTML 中成功。对于所有其他格式,数据库工具取消了我的导出请求。

标签: jquery python html json html-table


【解决方案1】:

这里是示例代码。

var tbl = $('table tr:has(td)').map(function(i, v) {
var $td =  $('td', this);
    return {
             Id: $td.eq(0).text(),
             Timestamp: $td.eq().text(),
             Artist_Name: $td.eq(2).text(),
             Tweet_Id: $td.eq(3).text()               
             Tweet: $td.eq(4).text()              
             User_name: $td.eq(5).text()               
             User_Id: $td.eq(6).text()                
             Followers: $td.eq(7).text()                
           }
}).get();

【讨论】:

  • 有 500,000 行,我不会惊讶 js 触发了一个错误,比如脚本需要太多时间来响应
  • map() 创建一个新数组,这意味着这将比 each() 消耗更多的资源 - 当您处理 500,000 行时,这一点值得注意。
  • 那么你应该使用 setTimeout 这将在 IE 中对很多行表现不佳
【解决方案2】:

你在使用 php 吗?如果是这样,您可以使用 HTML DOM 解析和 json_encode() 来做一些事情。

如果你想使用 jquery / javascript,这将是太大而无法处理 - 这是可能的,但使用 js 处理这么多数据并不是很好。但是,如果你只做一次,并且你真的下定决心要使用 JS——那么 SO 上有一个类似的问题......

看看这个小提琴...

http://jsfiddle.net/s4tyk/

var myRows = [];
var headersText = [];
var $headers = $("th");

// Loop through grabbing everything
var $rows = $("tbody tr").each(function(index) {
  $cells = $(this).find("td");
  myRows[index] = {};

  $cells.each(function(cellIndex) {
    // Set the header text
    if(headersText[cellIndex] === undefined) {
      headersText[cellIndex] = $($headers[cellIndex]).text();
    }
    // Update the row object with the header/cell combo
    myRows[index][headersText[cellIndex]] = $(this).text();
  });    
});

// Let's put this in the object like you want and convert to JSON (Note: jQuery will also do this for you on the Ajax request)
var myObj = {
    "myrows": myRows
};
alert(JSON.stringify(myObj));

这是个问题 How to convert the following table to JSON with javascript?

如果您需要 js 方面的帮助,尽管问,但这应该可以帮助您。

【讨论】:

    【解决方案3】:

    使用 Python 和 lxml package,您可以解析 HTML

    import lxml.html as LH
    import collections
    import itertools as IT
    import json
    
    Row = collections.namedtuple(
        'Row',
        'id timestamp artist tweet_id created_at tweet user_name user_id, followers')
    
    filename = '/tmp/test.html'
    root = LH.parse(filename)
    data = []
    result = {'data': data}
    for row in IT.starmap(Row, zip(*[iter(root.xpath('//tr/td/text()'))]*9)):
        data.append({'text':row.tweet, 'id':row.id, 'tweet_id':row.tweet_id})
    
    with open('/tmp/test.json', 'w') as f:
        json.dump(result, f, indent=2)
    

    处理一个带有 500K &lt;tr&gt; 标签的文件大约需要 50 秒,并且需要大约 910M RAM(将 HTML 加载到带有 root = LH.parse(filename) 的 DOM 中)。

    将 json 文件加载到 Python 字典中大约需要 2 秒:

    In [14]: time x = json.load(open('/tmp/test.json'))
    CPU times: user 1.80 s, sys: 0.04 s, total: 1.84 s
    Wall time: 1.85 s
    

    【讨论】:

    • 对我来说这只给出:{“数据”:[]}
    • 如果您的 HTML 看起来与您发布的内容不完全相同,则可能会发生这种情况。尝试使用root.xpath('//tr/td/text()')。 (我将编辑我的帖子以说明我的意思。)两个正斜杠告诉root.xpath 递归搜索所有tr 标签,而不仅仅是顶级标签。
    • 嗯,好的。那是我的错。 HTML 代码总是从行首开始。我编辑了这个例子,这样更容易阅读。认为这不会有什么不同。也会调整示例。
    • 等等——问题不是空格(缩进)。两个正斜杠解决的问题与以额外标签开头的 HTML 有关,例如 &lt;html&gt;&lt;body&gt;&lt;table&gt;&lt;tr&gt;... 这两个正斜杠告诉 XPath 向下搜索 &lt;html&gt;&lt;body&gt; 和任何其他标签,直到如果找到&lt;tr&gt;
    • 我尝试了几次调整。我的机器正在处理它只是永远不会结束。 2个多小时后我放弃了;(
    猜你喜欢
    • 2015-09-02
    • 2020-05-09
    • 2019-06-13
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    相关资源
    最近更新 更多