2016-08-24 28 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項目的一部分,那麼你只需要將httparty和nokogiri放入你的Gemfile中,並且不需要。

這個工作對我來說是Rails項目(LIB/scraper.rb)內:

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

它是一個rails項目的一部分。我只是在沒有require的情況下嘗試了它,除了之前的錯誤之外,還得到了未初始化的常量錯誤,所以我猜測它是必需的。 – NeyLive

+0

請務必將寶石添加到您的Gemfile並運行軟件包安裝。 –

+0

我把它們添加到Gemfile中,並運行bundle安裝。 – NeyLive

0

梅迪亞特在此:

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 

導致輸出這樣的:

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: 
... 

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進行導航導致至少一個假陽性以及內部選擇器的參加nil組。

相關問題