如何将HTML文档格式化为特定输出?

时间:2013-10-26 19:33:28

标签: ruby parsing nokogiri

我正在尝试将HTML文档处理为特定输出,我设法收到类似这样的内容:

<div class="country">
  <b>Austria</b>
  <div>Wolfhard</div>
</div>
<div class="country">
  <b>Bulgaria</b>
  <div>Nestor</div>
</div>
<div class="country">
  <b>Croatia</b>
  <div>Sabina</div>
  <div>Florencije</div>
</div>
<div class="country">
  <b>Czech Republic</b>
  <div>Šarlota</div>
  <div>Zoe</div>
</div>

我想要达到这样的目标:

Austria 
Wolfhard
Bulgaria
Nestor
Croatia
Sabina, Florencije
Czech Republic
Šarlota, Zoe

名称的最大数量为3。

1 个答案:

答案 0 :(得分:0)

您的HTML是无效的示例。使用有效的最小样本数据非常重要。

我不在我的电脑附近,但这看起来是正确的:

require 'nokogiri'
# encoding: utf8

html = '<html>
  <body>
    <div class="country">
      <b>Austria</b>
      <div>Wolfhard</div>
    </div>
    <div class="country">
      <b>Bulgaria</b>
      <div>Nestor</div>
    </div>
    <div class="country">
      <b>Croatia</b>
      <div>Sabina</div>
      <div>Florencije</div>
    </div>
    <div class="country">
      <b>Czech Republic</b>
      <div>Šarlota</div>
      <div>Zoe</div>
    </div>
  </body>
</html>'

doc = Nokogiri::HTML(html)

设置解析的DOM。因为有UTF-8字符,所以如果你使用Ruby&lt; v2.0,这就是编码行的原因:

# encoding: utf8

以下是搜索DOM的方法:

countries = doc.search('.country')
data = countries.map { |country|
  name = country.at('b').text
  cities = country.search('div').map(&:text)
  {
    :name => name,
    :cities => cities
  }
}

返回一个哈希数组,其中每个哈希包含国家名称和城市名称的子数组。从那里,您可以轻松地遍历数组并根据需要输出值。

这一切都非常简单,你只需要考虑增量步骤:

  1. 由于div标记有多个class="country",因此可以使用searchcss方法对其进行迭代。 css需要CSS选择器,而search允许CSS或XPath。我通常使用search因为有时候我会使用CSS,有时候会使用XPath,并且在我开发代码时可能会在它们之间跳转,因为一个人可能会更好地流动。除了选择器之外,还必须更改方法名称是一种痛苦。
  2. 对于每个选定的div,可以使用<b>轻松获取嵌入的at标记,该标记抓取第一个找到的匹配元素,然后search获取匹配的嵌入div城市。