这简直让我抓狂,在这里搜索,大G更让我困惑。
我遵循了Railscasts #190在Nokogiri上的教程,并能够自己编写一个漂亮的小解析器:
require 'rubygems'
require 'nokogiri'
require 'open-uri'
url = "http://www.target.com/c/movies-entertainment/-/N-5xsx0/Ntk-All/Ntt-wwe/Ntx-matchallpartial+rel+E#navigation=true&facetedValue=/-/N-5xsx0&viewType=medium&sortBy=PriceLow&minPrice=0&maxPrice=10&isleaf=false&navigationPath=5xsx0&parentCategoryId=9975218&RatingFacet=0&customPrice=true"
doc = Nokogiri::HTML(open(url))
puts doc.at_css("title").text
doc.css(".standard").each do |item|
title = item.at_css("span.productTitle a")[:title]
format = item.at_css("span.description").text
price = item.at_css(".price-label").text[/$[0-9.]+/]
link = item.at_css("span.productTitle a")[:href]
puts "#{title}, #{format}, #{price}, #{link}"
end
我对结果很满意,并且能够在Windows控制台中看到它。但是,我想将结果导出为CSV文件,并尝试了许多方法(没有运气),我知道我错过了一些东西。我最新更新的代码(下载html文件后)如下:
require 'rubygems'
require 'nokogiri'
require 'csv'
@title = Array.new
@format = Array.new
@price = Array.new
@link = Array.new
doc = Nokogiri::HTML(open("index1.html"))
doc.css(".standard").each do |item|
@title << item.at_css("span.productTitle a")[:title]
@format << item.at_css("span.description").text
@price << item.at_css(".price-label").text[/$[0-9.]+/]
@link << item.at_css("span.productTitle a")[:href]
end
CSV.open("file.csv", "wb") do |csv|
csv << ["title", "format", "price", "link"]
csv << [@title, @format, @price, @link]
end
它工作并为我吐出一个文件,但只是最后的结果。我遵循了Andrew的教程!:网页抓取……把我想要达到的目标和别人的过程混在一起会让人困惑。
我假设它循环遍历所有结果,只打印最后一个。有人能给我指点我应该如何循环这个(如果这是问题),以便所有的结果都在各自的列?
您将值存储在四个数组中,但是在生成输出时没有枚举这些数组。
这是一个可能的修复:
CSV.open("file.csv", "wb") do |csv|
csv << ["title", "format", "price", "link"]
until @title.empty?
csv << [@title.shift, @format.shift, @price.shift, @link.shift]
end
end
请注意,这是一个破坏性的操作,每次将数组中的值移开一个,因此最终它们将全部为空。
有更有效的方法来读取和转换数据,但希望这将满足您现在的需求。
要用"Ruby的方式"编写这段代码,你可以做以下几件事:
require 'rubygems'
require 'nokogiri'
require 'csv'
doc = Nokogiri::HTML(open("index1.html"))
CSV.open('file.csv', 'wb') do |csv|
csv << %w[title format price link]
doc.css('.standard').each do |item|
csv << [
item.at_css('span.productTitle a')[:title]
item.at_css('span.description').text
item.at_css('.price-label').text[/$[0-9.]+/]
item.at_css('span.productTitle a')[:href]
]
end
end
没有样本HTML是不可能测试的,但是,根据你的代码,它看起来是可行的。
注意,在你的代码中你使用了实例变量。它们不是必需的,因为您没有定义要拥有其实例的类。您可以使用本地值。