使用mechanize从HTML表中提取数据

时间:2014-05-06 16:51:34

标签: html ruby-on-rails ruby parsing mechanize

首先,这是示例html表:  

 <tr>
   <td><strong>Kangchenjunga </strong></td>
   <td>8,586m<br /></td>
   <td>28,169ft</td>
   <td><div align="center">Nepal/India </div></td>
   <td>1955; G. Band, J. Brown </td>
 </tr>

ARGV [0]将有一座山的名字(第一个colomn),返回值应该是最后一列,即第一次爬山的人。

所以我需要检查整行第一列是否是ARGV [0],如果是,那么我应该返回没有日期的最后一列。

require 'mechanize'
p=Mechanize.new.get('www.alpineascents.com/8000m-peaks.asp').body
if p.include?('<strong>'+ARGV[0])
   puts 'ok'
end

我已经得到以下内容,可以打印&#34;确定&#34;如果我在html文档的正文中有ARGV [0]。 如何搜索找到ARGV [0]的同一行的最后一列?

示例:

<tr>
 <td><strong>GIVE THIS AS A PARAMETER </strong></td>
 <td>SKIP THIS<br /></td>
 <td>SKIP THIS</td>
 <td><div align="center">SKIP THIS</div></td>
 <td>I WANT IT TO RETURN THIS</td>
</tr>

我是Ruby的新手

3 个答案:

答案 0 :(得分:3)

更简洁的版本更依赖于XPath的黑魔法:)

require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open('http://www.alpineascents.com/8000m-peaks.asp'))
last_td = doc./("//tr[td[strong[text()='#{ARGV[0]}']]]/td[5]")

puts last_td.text.gsub(/.*?;/, '').strip

答案 1 :(得分:2)

我相信这就是你想要的(你需要宝石安装nokogiri)

require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open('http://www.alpineascents.com/8000m-peaks.asp'))
rows = doc.search('//table')[6]./('tr')
rows.shift
rows.shift

rows.each do |row|
  if row.text.include? ARGV[0]
    puts row./('td')[4].text.gsub(/.*?;/, '').strip   
  end
end

答案 2 :(得分:1)

我看到的第一个错误就是你正在调用以下内容:

p=Mechanize.new.get('www.alpineascents.com/8000m-peaks.asp').body

不幸的是,从mechanize对象中抓取body将返回所有正文文本,就像在DOCTYPE body块中找到的一样。

此信息非常烦人,所以我建议您执行以下操作。 p=Mechanize.new.get('http://www.alpineascents.com/8000m-peaks.asp')

这将返回一个与(http://mechanize.rubyforge.org/Mechanize/Page.html

一起玩的Mechanize#Page对象

使用该对象,我们可以通过执行以下操作简单地执行nokogiris搜索的搜索;

elems = p.search('tr')

这将返回所有tr元素作为Nokogiri :: XML :: Element,我们可以非常干净地使用它来获取我们想要的信息。请注意,您可能想要使用IRB中的所有内容来确切地确定您需要的内容,但这个想法应该从以下内容中清楚:

elems.first.search('td').last.text将从我们之前搜索过的第一个tr元素返回最终的td元素文本。

如果您有任何疑问/希望我澄清,请随时提出。

我已经用机械化很长一段时间来攻击事物了。

编辑:

如果您希望能够使用某些参数查找值,这就是我想象您将解决问题的方法

values = {}
elems.each do |e|
  td = e.search('td')
  values[td.first.text] = td.last.text
end

当您填写值哈希值时,您可以执行以下操作:

如果ARG [0] =“珠穆朗玛峰”

然后

> values["Everest"] => "1953; Sir E. Hillary, T. Norgay"