2014-10-08 4 views
1

기본적으로 나는 각 페이지에 복수 .main_entry 개의 블록을 갖게 될 것이고 각각에서 몇 가지 데이터를 가져와야 할 것입니다. 어떻게 이것이 메소드로 적절하게 리팩토링 될 수 있습니까?리팩토링 루비 스크래핑 코드

require 'open-uri' 
require 'nokogiri' 


url = #url 
doc = Nokogiri::HTML(open(url)) 

doc.css(".main_entry").each do |item| 
    artist = item.at_css(".list_artist").text 
    title = item.at_css(".list_album").text 
    puts "#{artist} - #{title}" 
end 

내가 작성 오버되는 방법에 관련이있는 것으로 보인다 undefined local variable or method 'release' 오류가 발생합니다 아래의이 혼란에 도착했다. 아래 코드가 어떤 과정을 거쳐야하는지, 왜 고장이 났는지, 그리고 수정해야 할 부분을 설명해 주시겠습니까? 각 .main_entry 블록을 일종의 캐시 또는 배열에 먼저 저장해야합니까? 인스턴스화하기 전에? '그것을 대신

Scraper.new(url).releases.each do |release| 
    puts "#{release.artist} - #{release.title}" 
end 
+0

'release.each'는 인스턴스 메소드'release'를 호출하지 않지만 :

require 'open-uri' require 'nokogiri' class ScrapedRelease attr_reader :item def initialize(item) @item = item end def artist @artist ||= item.at_css(".list_artist").text end def title @title ||= item.at_css(".list_album").text end end class Scraper def initialize(url) @url = url end def releases @releases ||= (doc.css(".main_entry") || []).map { |item| ScrapedRelease.new(item) } end private attr_reader :url def doc @doc ||= Nokogiri::HTML(open(url)) end end 

그런 다음 당신이 할 수 있습니다 : 여기

require 'open-uri' require 'nokogiri' class Scraper def initialize(url) @url = url end def release @release ||= doc.css(".main_entry") || [] end release.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.artist} - #{scraper.title}" 
tadman

+0

@ tadman이 모양이 어땠 을까? 'def initialize (url, release) ... @release = Scraper.release' 그리고 나서 별도의'def release ... @release = ...'? – sivanes

+0

당신이하고 싶은 것을 보여주는 샘플 HTML을 제공해야합니다. 우리가 그것을 발명하도록 만들지 마라. –

답변

1

내 제안이다 당신이 정의하지 않은`Scraper.release`를 찾으러 갈 것입니다. `initialize` 메쏘드 안에서 항상 그것을 움직일 수 있습니다.
+0

우와, 놀랍다! 이와 같은 예를 공부하는 데 더 많은 시간을 할애해야합니다. – sivanes

+1

Btw, Ruby 2.x를 사용하고 있다면'(doc.css (". main_entry") || [])'대신'Array (doc.css (". main_entry"))'를 할 수 있습니다. 나에게 훨씬 더 우아하다. 'Array (nil)'은'[]'이기 때문입니다. – moonfly

+0

그래, 나는 '|| []'부분 만 검사 됨'nil || 콘솔에서'Array (nil)'이'nil'이라고 가정합니다. 그래서 당신이 이것을 분명히하는 것이 좋습니다! 그리고 네, 2.x를 사용하고 있습니다. – sivanes