还在学习如何使用nokogiri,到目前为止可以通过css元素抓取。有一个页面我想刮http://www.bbc.co.uk/sport/football/results,我想得到所有的结果为巴克莱英超联赛可以通过阿贾克斯调用渲染,但这是不可能的与nokogiri我读过。
所以我提供的链接有许多不同联赛的结果,所以我可以只抓取标题为"巴克莱英超"的结果吗?
class="competition-title"
目前我可以抓取所有的结果,像这样
def get_results # Get me all results
doc = Nokogiri::HTML(open(RESULTS_URL))
days = doc.css('#results-data h2').each do |h2_tag|
date = Date.parse(h2_tag.text.strip).to_date
matches = h2_tag.xpath('following-sibling::*[1]').css('tr.report')
matches.each do |match|
home_team = match.css('.team-home').text.strip
away_team = match.css('.team-away').text.strip
score = match.css('.score').text.strip
Result.create!(home_team: home_team, away_team: away_team, score: score, fixture_date: date)
end
感谢您的帮助
编辑ok,所以看起来好像我可以使用一些ruby,使用select?但不确定如何实现。在下面的示例
.select{|th|th.text =~ /Barclays Premier League/}
或者更多的阅读说可以使用xpath
matches = h2_tag.xpath('//th[contains(text(), "Barclays Premier League")]').css('tr.report')
或
matches = h2_tag.xpath('//b/a[contains(text(),"Barclays")]/../following-sibling::*[1]').css('tr.report')
尝试了xpath方法,但显然是错误的,因为没有保存
谢谢
我更喜欢一种深入到您所需要的东西的方法。查看源代码,您需要匹配细节:
<td class='match-details'>
<p>
<span class='team-home teams'><a href='...'>Brechin</a></span>
<span class='score'><abbr title='Score'> 0-2 </abbr></span>
<span class='team-away teams'><a href='...'>Alloa</a></span>
</p>
</td>
您需要p
元素中的三个文本内容项。你只需要"巴克莱英超"。
<th>
元素来识别。然后只需使用XPath标识该表:
matches = doc.xpath('//table[.//th[contains(., "Barclays Premier League")]]//td/p')
td/p
是足够的,因为匹配细节是唯一包含p
的,但是如果您愿意,您可以将该类添加到td
。
然后你完全按照你的方式获取你的信息:
matches.each do |match|
home_team = match.css('.team-home').text.strip
away_team = match.css('.team-away').text.strip
score = match.css('.score').text.strip
...
end
剩下一个任务:获取每场比赛的日期。回顾源代码,您可以追溯到第一个包含表,并看到前面的第一个h2
节点有它。可以用XPath表示:
date = match.at_xpath('ancestor::table[1]/preceding-sibling::h2[1]').text
把它们放在一起
def get_results
doc = Nokogiri::HTML(open(RESULTS_URL))
matches = doc.xpath('//table[.//th[contains(., "Barclays Premier League")]]//td/p')
matches.each do |match|
home_team = match.css('.team-home').text.strip
away_team = match.css('.team-away').text.strip
score = match.css('.score').text.strip
date = Date.parse(match.at_xpath('ancestor::table[1]/preceding-sibling::h2[1]').text).to_date
Results.create!(home_team: home_team, away_team: away_team, score: score, fixture_date: date)
end
end
只是为了好玩,下面是我将如何转换@Mark Thomas的解决方案:
def get_results
doc = Nokogiri::HTML(open(RESULTS_URL))
doc.search('h2.table-header').each do |h2|
date = Date.parse(h2.text).to_date
next unless h2.at('+ table th[2]').text['Barclays Premier League']
h2.search('+ table tbody tr').each do |tr|
home_team = tr.at('.team-home').text.strip
away_team = tr.at('.team-away').text.strip
score = tr.at('.score').text.strip
Results.create!(home_team: home_team, away_team: away_team, score: score, fixture_date: date)
end
end
end
首先遍历这些h2,得到:
优点:
- 将日期拉出循环
- 更简单的表达式(您可能不太担心这些)但是想想那个跟在你后面的人。)
缺点:
- 几个额外字节的代码