2016-08-24 2 views
0

나는 웹 스 크레이퍼를 만들고있어. 그래서 어떻게 배울 수 있는지.Ruby 및 Nokogiri에서이 정의되지 않은 메서드 오류가 발생하는 이유는 무엇입니까?

scraper.rb : 23 : 'item_container'에서 : 정의되지 않은 메서드 전무에 대한 'CSS'내가 터미널에서 실행할 때, 나는 내용의 오류 메시지가 무엇입니까 NilClass (NoMethodError)은 여기

은 내 scraper.rb의 코드

require 'HTTParty' 
require 'Nokogiri' 

class Scraper 

    attr_accessor :parse_page 

    def initialize 
    doc = HTTParty.get("http://store.nike.com/us/en_us/pw/mens-nikeid-lifestyle-shoes/1k9Z7puZoneZoi3") 
    @parse_page ||= Nokogiri::HTML(doc) #memoized @parse_page so it only gets assigned once. 
    end 

    def get_names 
    names = item_container.css(".product-name").css("p").children.map { |name| name.text }.compact 
    end 

    def get_prices 
    prices = item_container.css(".product-price").css("span.local").children.map { |price| price.text }.compact 
    end 

    private 
    def item_container 
    parse_page.css(".grid-item-info") 
    end 

    scraper = Scraper.new 
    names = scraper.get_names 
    prices = scraper.get_prices 

    (0...prices.size).each do |index| 
    puts "- - - index: #{index + 1} - - -" 
    puts "Name: #{names[index]} | Price: #{prices[index]}" 
    end 
end 

왜이 오류가 발생하는지 알려주실 수 있습니까? 어떻게 해결할 수 있습니까? 미리 감사드립니다.

+0

필자는'require'에 전달 된 값을 소문자로 입력해야한다고 생각합니다. 그렇게 한 후에,이 코드는 나를 위해 일했습니다. – pdoherty926

+0

나는 당신이 추천 한대로했다. 여전히 같은 오류가 발생합니다. – NeyLive

+0

그게 바로 Ruby 2.3.1입니다. Nokogiri의 어떤 버전을 설치하셨습니까? – NeyLive

답변

0

이 질문은 [ruby-on-rails]로 태그되었습니다. Rails 프로젝트의 일부인 경우 httpsy와 nokogiri를 Gemfile에 넣기 만하면되므로 필요하지 않습니다. 이에

class Scraper 

    attr_accessor :parse_page 

    def initialize 
    doc = HTTParty.get("http://store.nike.com/us/en_us/pw/mens-nikeid-lifestyle-shoes/1k9Z7puZoneZoi3") 
    @parse_page ||= Nokogiri::HTML(doc) #memoized @parse_page so it only gets assigned once. 
    end 

    def get_names 
    names = item_container.css(".product-name").css("p").children.map { |name| name.text }.compact 
    end 

    def get_prices 
    prices = item_container.css(".product-price").css("span.local").children.map { |price| price.text }.compact 
    end 

    private 

    def item_container 
    parse_page.css(".grid-item-info") 
    end 

end 
+0

이것은 레일 프로젝트의 일부입니다. 난 그냥 필요없이 시도하고 이전 오류 이외에, 초기화되지 않은 상수 오류가있어, 그래서 그것이 필요하다고 생각해. – NeyLive

+0

Gemfile에 보석을 추가하고 번들 설치를 실행하십시오. –

+0

나는 그것들을 Gemfile에 추가했고 번들 설치를 실행했다. – NeyLive

0

미디 에이트 :

은 레일 프로젝트 (lib 디렉토리/scraper.rb)의 내부에 나를 위해 일한

1: Name: Nike Sock Dart iD | Price: $170 | Override price: 
2: Name: Nike Air Max 1 Ultra Flyknit iD | Price: $200 | Override price: 
3: Name: Nike Air Max 1 Premium iD | Price: $175 | Override price: 
4: Name: Nike Air Max 90 Premium iD | Price: $175 | Override price: 
5: Name: Nike Air Force 1 High Premium iD | Price: $175 | Override price: 
6: Name: Nike Air Force 1 Mid Premium iD | Price: $170 | Override price: 
... 
이 같은 출력 결과

require 'httparty' 
require 'nokogiri' 

class Scraper 

    attr_accessor :parse_page 
    attr_reader :url 

    def initialize(url) 
    @url ||= url 
    @parse_page ||= Nokogiri::HTML(HTTParty.get(url)) 
    end 

    def names_and_prices 
    @parse_page.search('div.product-name').map{ |shoe| 
     shoe_parent = shoe.parent 
     name = shoe_parent.at('p.product-display-name').text 

     product_prices = shoe_parent.at('div.prices') 
     override_price = product_prices.at('span.overridden').text 
     price = product_prices.at('span.local').text 

     { 
     name: name, 
     price: price, 
     override_price: override_price 
     } 
    } 
    end 

end 

scraper = Scraper.new('http://store.nike.com/us/en_us/pw/mens-nikeid-lifestyle-shoes/1k9Z7puZoneZoi3') 

scraper.names_and_prices.each_with_index do |shoe, index| 
    puts "#{index + 1}: Name: #{shoe[:name]} | Price: #{shoe[:price]} | Override price: #{shoe[:override_price]}" 
end 

scraper.names_and_prices은 다음과 같이 보이는 배열 배열을 반환합니다.

[ 
    [0] { 
    :name   => "Nike Sock Dart iD", 
    :price   => "$170", 
    :override_price => "" 
    }, 
    [1] { 
    :name   => "Nike Air Max 1 Ultra Flyknit iD", 
    :price   => "$200", 
    :override_price => "" 
    } 
] 

스크래핑 할 때 원하는 내용을 빠르게 찾을 수있는 마크 업에서 가장 좋은 랜드 마크를 찾으려면 HTML을 파헤쳐 야합니다. div.product-name은 실제로 내가 원하는 것보다 한 단계 더 깊기 때문에 shoe.parent은 원하는 정보가 들어있는 부모 노드에 한 수준을 백업합니다. 결과적으로 코드는 각 신발에 대한 정보를 깨끗하게 검색 할 수 있습니다. .grid-item-info을 사용하여 네비게이션하면 내부 선택기에 대한 nils 세트와 함께 적어도 하나의 거짓 긍정 (false positive)이 발생합니다.

관련 문제