2013-03-16 2 views
1

Что я пытаюсь сделать, это очистить имена и цены товаров от нескольких поставщиков, использующих Nokogiri. Я передаю селекторы CSS (к именам и ценам поиска) в Nokogiri с аргументами метода.Итерация по нескольким URL-адресам для анализа HTML-кода с помощью Nokogori

Любые указания о том, как передавать несколько URL-адресов методу «scrape», а также передавать другие аргументы (например: vendor, item_path)? Или я об этом совершенно неправильно?

Вот код:

require 'rubygems' # Load Ruby Gems 
require 'nokogiri' # Load Nokogiri 
require 'open-uri' # Load Open-URI 

@@collection = Array.new # Array to hold meta hash 

def scrape(url, vendor, item_path, name_path, price_path) 
    doc = Nokogiri::HTML(open(url)) # Opens URL 
    items = doc.css(item_path) # Sets items 
    items.each do |item| # Iterates through each item on grid 
     @@collection << meta = Hash.new # Creates a new hash then add to global array 
     meta[:vendor] = vendor 
     meta[:name] = item.css(name_path).text.strip 
     meta[:price] = item.css(price_path).to_s.scan(/\d+[.]\d+/).join 
    end 
end 

scrape("page_a.html", "Sample Vendor A", "#products", ".title", ".prices") 
scrape(["page_a.html", "page_b.html"], "Sample Vendor B", "#items", ".productname", ".price") 

ответ

1

Вы можете передать несколько url's так же, как вы уже делаете это в вас второй пример:

scrape(["page_a.html", "page_b.html"], "Sample Vendor B", "#items", ".productname", ".price") 

Ваш метод scrape будет перебирать те urls, например:

def scrape(urls, vendor, item_path, name_path, price_path) 
    urls.each do |url| 
    doc = Nokogiri::HTML(open(url)) # Opens URL 
    items = doc.css(item_path) # Sets items 
    items.each do |item| # Iterates through each item on grid 
     @@collection << meta = Hash.new # Creates a new hash then add to global array 
     meta[:vendor] = vendor 
     meta[:name] = item.css(name_path).text.strip 
     meta[:price] = item.css(price_path).to_s.scan(/\d+[.]\d+/).join 
    end 
    end 
end 

Это также означает, что первый пример также должен быть передан как массив:

scrape(["page_a.html"], "Sample Vendor A", "#products", ".title", ".prices") 
+0

Спасибо! Это отлично работает. Я не знал, что мне пришлось передать первый пример как массив. –

1

FYI, используя @@collection нецелесообразно. Вместо этого, написать метод для возвращения значения:

def scrape(urls, vendor, item_path, name_path, price_path) 
    collection = [] 
    urls.each do |url| 
    doc = Nokogiri::HTML(open(url)) # Opens URL 
    items = doc.css(item_path) # Sets items 
    items.each do |item| # Iterates through each item on grid 
     collection << { 
     :vendor => vendor, 
     :name => item.css(name_path).text.strip, 
     :price => item.css(price_path).to_s.scan(/\d+[.]\d+/).join 
     } 
    end 
    end 

    collection 
end 

Что может быть уменьшена до:

def scrape(urls, vendor, item_path, name_path, price_path) 
    urls.map { |url| 
    doc = Nokogiri::HTML(open(url)) # Opens URL 
    items = doc.css(item_path) # Sets items 
    items.map { |item| # Iterates through each item on grid 
     { 
     :vendor => vendor, 
     :name => item.css(name_path).text.strip, 
     :price => item.css(price_path).to_s.scan(/\d+[.]\d+/).join 
     } 
    } 
    } 
end 
+0

Использование второго метода, который вы предложили, просто уменьшил мое реальное время выполнения пополам. С моим исходным кодом я использовал это, чтобы распечатать данные: 'def list_matches @@ collection.each do | k | пут "Производитель: # {к [: поставщику]}" пут "Имя: # {к [: имя]}" пут "Цена: $ # {к [: цена]}" конец end' Как я могу сделать то же самое с вашим методом? Спасибо за помощь. –

+0

Хех, чудеса не прекратятся? Все, что я могу сказать, иногда мне повезло. :-) На самом деле, есть образцы, которые мы повторно используем снова и снова в нашем кодировании, и, сверхурочно, мы должны научиться распознавать определенные виды использования/приложения кода и сразу же обращаться к ним. Второе - сокращение первого, и это результат слишком многих лет написания кода на разных языках. Хорошо, что я смог помочь. –