【问题标题】:How do I create JSON from parsed HTML table using Nokogiri?如何使用 Nokogiri 从解析的 HTML 表创建 JSON?
【发布时间】:2013-09-13 05:45:31
【问题描述】:

我想从this site 的每个TR 创建一个JSON 对象。

现在我可以得到整张桌子和每个TR,但这还不够……这就是我感到困惑的原因。

这是我想要作为回报的 JSON 示例。这是第07章的:

{
  "chapter":"07",
  "title":"LIFTING AND SHORING",
  "description":"This chapter shall...",
  "section":[
    {
      "number":"00",
      "title":"GENERAL",
      "description":"",
    },

    {
      "number":"10",
      "title":"JACKING",
      "description":"Provides information relative...",
    },

    {
      "number":"20",
      "title":"SHORING",
      "description":"Those instructions necessary...",
    }
  ]
}

我需要的是立即完成这一切,但这是我迄今为止所管理的:

parsed_html.css("table")[1].css("tr")

我正在使用 Nokogiri 进行解析。

【问题讨论】:

    标签: ruby json css-selectors html-parsing nokogiri


    【解决方案1】:

    这对于学习 Ruby 来说真的不是问题。数据笨拙且不可靠,对于您相对熟悉的语言来说,这将是一个有用的编程挑战。当您学习一门语言时,您需要的任务相对简单,但会测试您对语言本身的了解。

    我已经写了这个,它至少符合你在章节07 中的示例。

    它的工作原理是从页面中选择一个(唯一的)具有多行的表格。然后它遍历这些行,提取字段数组,将不可破坏的空格转换为普通空格,并去除前导和尾随空格。丢弃所有空字段,如果不包含数据,则忽略整行。

    然后第一列以十进制数字开头的行表示章节的第一行,或者如果前面有连字符则表示同一章节的章节信息。

    如果源中缺少某个字段(描述 字段和部分标题),我通常会选择从中间数据中省略它。但是,我已将这些字段默认为空字符串,以符合您的预期 JSON 输出示例。 (不存在的散列元素与值为nil 的散列元素之间存在差异。)

    我希望这会有所帮助。

    require 'open-uri'
    require 'nokogiri'
    require 'json'
    
    open('http://www.s-techent.com/ATA100.htm') do |f|
    
      doc = Nokogiri::HTML(f)
      table = doc.at_xpath('//table[count(tr) > 1]')
    
      chapters = []
      chapter = nil
    
      table.xpath('tr').each do |tr|
    
        td = tr.xpath('td')
        td = td.map { |td| td.content.gsub("\u00A0", ' ').strip }
        td = td.select { |txt| not txt.empty? }
        next if td.empty?
    
        if td[0] =~ /^\d+/
    
          chapters << chapter if chapter
    
          chapter = {
              'chapter'     => td[0],
              'title'       => td[1],
              'description' => td[2] || ''
          }
    
        elsif td[0] =~ /^-(\d+)/
    
          section = {
              'number'      => $1,
              'title'       => td[1] || '',
              'description' => td[2] || ''
          }
    
          chapter['section'] ||= []
          chapter['section'] << section
        end
    
      end
    
      chapters << chapter if chapter
    
      puts JSON.pretty_generate(chapters)
    
    end
    

    (部分)输出

    {
      "chapter": "07",
      "title": "LIFTING AND SHORING",
      "description": "This chapter shall include the necessary procedures to lift and shore aircraft in any of the conditions to which it may be subjected.  Includes lifting and shoring procedures that may be employed during aircraft maintenance and repair.",
      "section": [
        {
          "number": "00",
          "title": "GENERAL",
          "description": ""
        },
        {
          "number": "10",
          "title": "JACKING",
          "description": "Provides information relative to jack points, adapters, tail supports, balance weights, jacks and jacking procedures utilized during aircraft maintenance and repair."
        },
        {
          "number": "20",
          "title": "SHORING",
          "description": "Those instructions necessary to support the aircraft during maintenance and repair.  Includes information on shoring materials and equipment, contour dimensions, shoring locations, etc."
        }
      ]
    },
    

    【讨论】:

    • 你在这里做了什么……我惊呆了!现在我知道为什么这项任务对我来说如此重要。您的答案正是我所寻找的并澄清了一切。我欠你一品脱好啤酒:)
    【解决方案2】:

    这个问题一般来说非常困难,因为标记是手动完成的,而且非常糟糕,并且没有可靠的方法可以跨更新提取数据。

    例如

    • 两个第01章:简介操作信息

    • 章节编号有时只是数字,如@9​​87654321@,有时是混合的,如72(R)

    • 最多 23 章的标题在第二列,colspan="2" 属性在 td 元素上,但之后的章节第二列为空白,标题在第三列

    • 不可破坏的空格 U+00A0 存在不稳定和虚假使用,String 类无法将其识别为空格

    • 有带有bgcolor="#CCCCCC" 的灰色背景的空白行可用于分隔章节信息。但是我们再次依赖手动输入的准确性

    • 表中的GROUP DEFINITION行有什么需要做的吗?

    如果程序不必从其他类似页面或同一页面的(手动)修改版本中提取数据,这将相当简单。否则你不得不承认手动输入的数据无法解析而放弃。

    【讨论】:

    • 不,组定义没有什么可做的,我认为最好的解决方案是使用灰色线条分隔章节(但不知道如何......)。我只需要从这个特定的页面中提取数据,它是一次性的,因为我想练习 Ruby 并避免一些手动工作。我需要这个适用于 iOS 应用程序的 JSON。
    猜你喜欢
    • 2011-01-04
    • 2013-08-15
    • 2011-09-08
    • 2013-04-19
    • 2012-02-03
    • 2013-04-27
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多