структурирование CSV в формате строки и столбца с рельс - PullRequest
0 голосов
/ 24 июня 2019

Я создал небольшое веб-приложение для очистки с помощью ruby, с помощью которого я собираю данные с веб-сайта и затем сохраняю их в CSV-файле. Я удаляю и сохраняю все успешно, однако я не могу структурировать мой CSV-файл в формате таблицы, в котором есть два столбца и несколько строк. Мой CSV-файл должен иметь столбец с именем и столбец цены, с названием и ценой каждого товара. Это мой код:

require 'open-uri'
require 'nokogiri'
require 'httparty'
require 'byebug'
require 'csv'

    def whey_scrapper
        company = 'Body+%26+fit'
        url = "https://www.bodyenfitshop.nl/eiwittenwhey/whey-proteine/?limit=81&manufacturer=#{company}"
        unparsed_page = open(url).read
        parsed_page = Nokogiri::HTML(unparsed_page)
        product_names = parsed_page.css('div.product-primary')
        name = Array.new
        product_names.each do |product_name| 
            name << product_name.css('h2.product-name').text
        end
        product_prices = parsed_page.css('div.price-box')
        price = Array.new
        product_prices.each do |product_price|
            price << product_price.css('span.price').text
        end
        headers = ["name", "price"]
        item = [name, price]
        CSV.open('data/wheyprotein.csv', 'w', :col_sep => "\t|", :headers => true) do |csv|
            csv << headers
            item.each {|row| csv << row }
        end
        byebug
    end   
    whey_scrapper

Я создаю строку после каждой итерации элемента, однако файл csv по-прежнему очень неструктурированный и грязный.

Вот так выглядит мой CSV-файл:

name	|price
-----------------
"
                            
                                Whey Perfection                                Body & fit
                            
                        "	|"
                            
                                Whey Perfection® bestseller box                                Body & fit
                            
                        "	|"
                            
                                Whey Perfection - Special Series                                Body & fit
                            
                        "	|"
                            
                                Isolaat Perfection                                Body & fit
                            
                        "	|"
                            
                                Perfect Protein                                Body & fit
                            
                        "	|"
                            
                                Whey Isolaat XP                                Body & fit
                            
                        "	|"
                            
                                Micellar Casein Perfection                                Body & fit
                            
                        "	|"
                            
                                Low Calorie Meal                                Body & fit
                            
                        "	|"
                            
                                Whey Breakfast                                Body & fit
                            
                        "	|"
                            
                                Whey Perfection - Flavour Box                                 Body & fit
                            
                        "	|"
                            
                                Protein Breakfast                                Body & fit
                            
                        "	|"
                            
                                Whey Perfection Summer Box                                Body & fit
                            
                        "	|"
                            
                                Puur Whey                                Body & fit
                            
                        "	|"
                            
                                Whey Isolaat Crispy                                Body & fit
                            
                        "	|"
                            
                                Vegan Protein voordeel                                Body & fit vegan
                            
                        "	|"
                            
                                Whey Perfection Winter Box                                Body & fit
                            
                        "	|"
                            
                                Sports Breakfast                                Body & fit
                            
                        "
€ 7,90	|€ 9,90	|€ 11,90	|€ 17,90	|€ 31,90	|€ 18,90	|€ 12,90	|€ 6,90	|€ 6,90	|€ 10,90	|€ 15,90	|€ 9,90	|€ 26,90	|€ 6,90	|€ 24,90	|€ 9,90	|€ 20,90

1 Ответ

1 голос
/ 24 июня 2019

Прежде всего - названия продуктов. Вы извлекаете слишком много информации из HTML. Элемент h2 содержит пробелы и элемент span внутри, которые, вероятно, следует игнорировать. Вы можете сделать это так:

product_names.each do |product_name| 
  name << product_name.css('h2.product-name a').children[0].text.gsub(/\s{2,}/, '')
end

Затем CSV требует передачи каждой строки в виде массива с несколькими элементами. В вашем случае должно быть много массивов с двумя элементами (название продукта и цена). Для этого вы можете просто сжать две таблицы:

items = name.zip(price)

А затем создайте файл CSV:

CSV.open('data/wheyprotein.csv', 'w') do |csv|
  csv << headers
  items.each {|row| csv << row }
end

Полный метод выглядит следующим образом:

def whey_scrapper
    company = 'Body+%26+fit'
    url = "https://www.bodyenfitshop.nl/eiwittenwhey/whey-proteine/?limit=81&manufacturer=#{company}"
    unparsed_page = open(url).read
    parsed_page = Nokogiri::HTML(unparsed_page)
    product_names = parsed_page.css('div.product-primary')
    name = Array.new
    product_names.each do |product_name| 
        name << product_name.css('h2.product-name a').children[0].text.gsub(/\s{2,}/, '')
    end
    product_prices = parsed_page.css('div.price-box')
    price = Array.new
    product_prices.each do |product_price|
        price << product_price.css('span.price').text
    end
    headers = ["name", "price"]
    items = name.zip(price)
    CSV.open('data/wheyprotein.csv', 'w+') do |csv|
        csv << headers
        items.each {|row| csv << row }
    end
end   
...