我想重拍伦敦2012年的奥运奖牌数,以更好地反映奖牌的价值。目前它只按金牌排序。我想用积分来重新计算,所以gold = 4,silver = 2和bronze = 1来制作一个更合理的新列表。我可能想记住之前的排名,然后添加一个新的排名列。
我想尝试机械化从站点获取原始数据,然后将数据解析为行和列,应用新计数,然后重新制作列表。
从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')它会显示整个列表。如何解析特定的跨度和表数据?
我还需要记住排名,然后当我创建新页面时,将新排名放在旁边。
任何有关机械化解析和记忆数据的提示都会非常有用。更重要的是你做这样的事情的思考过程,我很感激帮助我开始。这不一定是代码答案
由于
答案 0 :(得分: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"
答案 1 :(得分:1)
您可能会发现此Medals API很有用(假设您的问题并非专门针对Mechanize)
http://apify.heroku.com/resources/5014626da8cdbb0002000006
它使用Nokogiri来解析网站,输出可用作JSON: