我正在努力刮http://www.ign.com/games/reviews使用Nokogiri,我想实例化与页面上的每个游戏评论相对应的新评论对象。当然,我也想从每个评论中获取每个数字Score,并将该分值作为类属性分配给我的评论对象。
问题是,我能做的最好的事情就是返回一整串拼凑在一起的分数,而不是由每个分数组成的列表。
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选择器?
您正确使用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中的:each方法将始终返回调用它的原始集合。因此,例如以下将返回[1,2]
:
[1,2].each do |n|
n * 4
end