Nokogiri并从一个充满Nokogiri节点的阵列中隔离选择元素

时间:2016-05-14 02:01:23

标签: css ruby nokogiri

我试图使用Nokogiri抓取http://www.ign.com/games/reviews,并且我想要实例化与页面上每个游戏评论相对应的新评论对象。当然,我也想从每个评论中获取每个数字分数,并将该分数值作为类属性分配给我的评论对象。

问题是,我能做的最好的事情是返回一整套得分而不是由每个得分组成的列表。

class VideoGameReviews::Review
  attr_accessor :name, :score, :url

  def self.scrape_titles
    @doc = Nokogiri::HTML(open("http://www.ign.com/games/reviews?"))

    @doc.search("#item-list div.itemList div.itemList-item").each do |review|
      new_review = VideoGameReviews::Review.new

      new_review.score = review.search("span.scoreBox-score").text
      => "99996.37.17.17.17778.58.58.586.36.47.187.57.88.95.587.6" #Not what I want
    end
  end

end

有关如何从每个分数中提取分数列表的任何建议与其他分数分开且独特吗?也许使用更具体的CSS选择器?

1 个答案:

答案 0 :(得分:0)

您正在使用nokogiri,但需要修改逻辑以正确存储分数。例如,我们可以非常轻松地获得单个游戏的得分:

new_review.score = fourth_item.search("span.scoreBox-score").text
=> "6.3" 

您可以先将代码分解为更小的方法,然后根据需要缓存值,而不必在单个方法中执行所有操作。我也会改变这个类名,因为你的Review类既代表Review项也代表一个擦除(违反单一责任原则)。也许像下面这样的东西会更好?

require ‘nokogiri’

class VideoGameReviews::ReviewScraper

  def reviews
    @reviews ||= Nokogiri::HTML(open("http://www.ign.com/games/reviews?"))
  end

  def review_items
    @review_items ||= reviews.search("#item-list div.itemList div.itemList-item")
  end

  def store_reviews
    review_items.each do |review|
      new_review = VideoGameReviews::Review.new #Review class still  used to save review
      new_review.score = review.search("span.scoreBox-score").text
      #get other data
      new_review.save! #or however you plan on persisting the data
    end
  end

end

问题是:你将如何保存评论(在本地内存中,在数据库中等)?对于快速的事情,ActiveRecord非常简单(并且您可以独立于Rails使用它。)

请注意:Ruby中的每个方法都将返回调用它的原始集合。例如,以下内容将返回[1,2]

[1,2].each do |n|
  n * 4
end