我正在从网页中检索数据。有多次出现类似结构的important
块,我将通过迭代使用更多方法。有没有办法让像下面的东西一样?
require 'open-uri'
require 'nokogiri'
class Scraper
def initialize(url)
@url = url
end
def name
@name ||= doc.at_css(".currentverylong").text
end
def important
@important = doc.css(".main_entry")
end
important.each do |item|
define_method(:artist) do
@artist ||= item.at_css(".list_artist").text
end
define_method(:title) do
@title ||= item.at_css(".list_album").text
end
end
private
attr_reader :url
def doc
@doc ||= Nokogiri::HTML(open(url))
end
end
scraper = Scraper.new( #url
puts scraper.name
puts "#{scraper.artist} \"#{scraper.title}\" "
现在的方式,错误是important
未定义。取消important
并将其替换为doc.css(."main_entry").each do |item|
也存在同样的问题。这也引出了另一个问题。为什么下面这样的方法接受doc
就好了?
def name
@name ||= doc.at_css(".currentverylong").text
end
更新
正如有人在这里提到的那样以及对SO的另一个相关问题的回应,important
被反复覆盖的事实就是这里的问题。有人可以解释一下这个过程中究竟发生了什么,以及导致undefined local variable or method
important
的原因是什么?
答案 0 :(得分:1)
如果您不希望重要的是返回nil,您可以使用important
方法的默认空数组值。
def important
@important ||= doc.css(".main-entry") || []
end
如果可能doc
将为零(不确定您是如何加载该网址),则可以使用try
来获取该空数组语句。
def important
@important ||= doc.try(:css, ".main-entry") || []
end
这将保证important
产生一个数组对象。