2012-08-03 27 views
1

我想重塑2012年伦敦的奥运奖牌,以更好地反映奖牌的价值。目前它只是通过金牌排序。我想用点数来重新设定它,所以黄金= 4,银色= 2和铜牌= 1来创建一个更加合理的列表。我可能想记住以前的排名,然后添加一个新的排名栏。使用Ruby和机械化来制作新的奥运奖牌

我想尝试机械化从站点获取原始数据,然后将数据解析为行和列,应用新计数,然后重新创建列表。

从源在http://www.london2012.com/medals/medal-count/每个国家具有像这样的奖牌的块:

<span class="countryName">Canada</span></a></div></div></td><td class="gold c">0</td><td class="silver c">2</td><td class="bronze c">5</td> 

如果使用agent.get( 'http://www.london2012.com/medals/medal-count')它显示了整个列表。如何解析特定的跨度和表格数据?

我还需要记住等级,然后当我在新页面上放置新的等级时。

机械化分析和记忆数据的任何提示将非常有帮助。更重要的是你在做这样的事情时的思考过程,我很乐意帮助我开始。这不一定是代码回答

谢谢

回答

2

首先识别表。在Chrome中加载页面并右键单击桌面上的任意位置。去检查元素。直到你坐在桌子上。现在选择它,你会看到它看起来像这样:

<table class="or-tbl overall_medals sortable" summary="Schedule"> 

的overall_medals类看起来将是唯一的所以这是一个很好的使用。现在启动IRB做:

require 'mechanize' 
agent = Mechanize.new 
page = agent.get 'http://www.london2012.com/medals/medal-count/' 

仔细检查该表是唯一的:

page.search('table.overall_medals').size 
#=> 1 (good, it is) 

您可以从表中的所有数据与数组:

page.search('table.overall_medals tr').map{|tr| tr.search('td').map(&:text)} 

公告前两行是空的,我们通过使用范围来摆脱它们:

data = page.search('table.overall_medals tr')[2..-1].map{|tr| tr.search('td').map(&:text)} 

第二行不是真的空,它有列名(在th中而不是在td中)。你可以得到那些有:

columns = page.search('table.overall_medals tr[2] th').map{|th| th.text.strip} 

你可以到这些哈希有:

rows = data.map{|row| Hash[columns.zip row]} 

现在你可以做

rows[0]['Country'] 
#=> "United States of America" 

甚至一个大哈希:

countries = rows.map{|row| {row['Country'] => row}}.reduce &:merge 

现在:

countries['France']['Gold'] 
#=> "8" 
+0

哇......&:&text&&merge items是做什么的?从上面开始的第四个代码块是映射一个搜索的地图,所以我想知道你是否可以将这些内容放在文字中。接下来从2到-1,我认为这是开始,所以我没有在那里。 – sf2k 2012-08-04 06:52:33

+0

rows = data.map {| row |哈希[columns.zip行]}你可以在这里解释一下zip吗? – sf2k 2012-08-04 06:58:06

+0

地图(&:text)是地图{| x |的快捷方式x.text},和&:merge一样。 columns.zip(row)将排列如下所示的行:[[column [0],row [0]],[column [1],row [1]]等],因此它可以很容易地放入哈哈 – pguardiario 2012-08-04 08:21:46