我想重新计算2012年伦敦奥运会的奖牌数,以更好地体现奖牌的值(value)。目前仅按金牌排序。我想按分数重新列出它,所以金=4,银=2 和铜=1 来制作一个新的更合理的列表。我可能想记住之前的排名,然后再添加一个新的排名列。
我想尝试 Mechanize 以从站点获取原始数据,然后将数据解析为行和列,应用新计数,然后重新制作列表。
来自 http://www.london2012.com/medals/medal-count/ 的来源每个国家都有一 block 像这样的奖牌:
<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') 它会显示整个列表。如何解析具体的span和表数据?
我还需要记住排名,然后在制作新页面时将新排名放在旁边。
任何关于 Mechanize 解析和内存数据的技巧都会很有帮助。更重要的是你在做这样的事情时的思考过程,我很感激帮助我开始。这不一定是代码答案
谢谢
最佳答案
首先要识别表。在 chrome 中加载页面并右键单击表格上的任意位置。去检查元素。上层级直到你在 table 上。现在选择它,您会看到它看起来像这样:
<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)}
注意前 2 行是空的,让我们使用一个范围来去掉它们:
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"
关于ruby - 使用 Ruby 和 Mechanize 计算新的奥运奖牌数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11804226/