抓取包含文本nokogiri xpath的元素



还在学习如何使用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元素中的三个文本内容项。你只需要"巴克莱英超"。

查看源代码,注意上面需要的元素恰好在一个表中,该表只包含该联赛的分数。多方便啊!这个表可以通过包含"Barclays Premier League"的<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,得到:

优点:

  • 将日期拉出循环
  • 更简单的表达式(您可能不太担心这些)但是想想那个跟在你后面的人。)

缺点:

  • 几个额外字节的代码

相关内容

  • 没有找到相关文章

最新更新