【问题标题】:ruby/nokogiri scraping - export to multiple CSVs, then take columns from each and combine into final CSVruby/nokogiri 抓取 - 导出到多个 CSV,然后从每个 CSV 中获取列并组合成最终的 CSV
【发布时间】:2014-09-10 04:33:52
【问题描述】:

Ruby n00b 在这里。我两次抓取同一页面 - 但每次都以稍微不同的方式 - 并将它们导出到单独的 CSV 文件。然后我想将 CSV no.1 的第一列和 CSV no.2 的第二列结合起来创建 CSV no.3。

提取 1 号和 2 号 CSV 的代码有效。但是添加我尝试将两个 CSV 合并到第三个(在底部注释掉)返回以下错误 - 两个 CSV 填充正常,但第三个保持空白并且脚本处于似乎是无限循环的状态。我知道这些线不应该在底部,但我看不出它还能去哪里......

alts.rb:45:in `block in <main>': undefined local variable or method `scrapedURLs1' for main:Object (NameError)
    from /Users/JammyStressford/.rvm/rubies/ruby-2.0.0-p451/lib/ruby/2.0.0/csv.rb:1266:in `open'
    from alts.rb:44:in `<main>'

代码本身:

require 'rubygems'
require 'nokogiri'   
require 'open-uri'
require 'csv'


url = "http://www.example.com/page"
page = Nokogiri::HTML(open(url))


CSV.open("results1.csv", "wb") do |csv|
  page.css('img.product-card-image').each do |scrape|
    product1 = scrape['alt']
    page.css('a.product-card-image-link').each do |scrape|
      link1 = scrape['href']

      scrapedProducts1 = "#{product1}"[0..-7]
      scrapedURLs1 = "{link1}"

      csv << [scrapedProducts1, scrapedURLs1]
    end
  end
end

CSV.open("Results2.csv", "wb") do |csv|
  page.css('a.product-card-image-link').each do |scrape|
    link2 = scrape['href']
    page.css('img.product-card-image').each do |scrape|
      product2 = scrape['alt']

      scrapedProducts2 = "#{product2}"[0..-7]
      scrapedURLs2 = "http://www.lyst.com#{link2}"

      csv << [scrapedURLs2, scrapedProducts2]
    end
  end
end

## Here is where I am trying to combine the two columns into a new CSV. ##
## It doesn't work. I suspect that this part should be further up...    ##

# CSV.open("productResults3.csv", "wb") do |csv|
  # csv << [scrapedURLs1, scrapedProducts2]
#end
puts "upload complete!"

感谢阅读。

【问题讨论】:

    标签: ruby-on-rails ruby web-scraping nokogiri export-to-csv


    【解决方案1】:

    感谢您分享您的代码和您的问题。希望我的意见有所帮助!

    • 您的scrapedURLs1 = "{link}" 和scrapedProducts1 = "#{scrape['alt']}"[0..-7] 末尾有一个1,但您没有在csv &lt;&lt; [scrapedProducts, scrapedURLs] 上调用它这是您遇到的错误强>

    • 我建议您将前两个步骤结合起来跳过 写入文件,但写入数组数组,然后你可以写 提交文件。

    • 您是否意识到在您给出的示例代码中 scrapedURLs1, scrapedProducts2 会将错误的网址混合到 错误的产品。这就是你的意思吗?

    • 在注释掉的代码scrapedURLs1, scrapedProducts2 内不存在,它们没有被声明。您需要打开两个文件以使用.each do |scrapedURLs1| 读取,然后使用.each do |scrapedProducts2| 打开另一个文件,然后这些变量将存在,因为each 枚举器实例化了它们。

    在内部迭代中重复使用相同的 |scrape| 变量不是一个好主意。将名称更改为其他名称,例如 |scrape2| 。它“发生”工作,因为您已经在第二个循环之前在product=scrape['alt'] 中获取了您需要的内容。如果您重命名第二个循环变量,您可以将product=scrape['alt'] 行移动到内部循环中并将它们组合起来。示例:

    # In your code example you may get many links per product.
    # If that was your intent then that may be fine.
    # This code should get one link per product.
    CSV.open("results1.csv", "wb") do |csv|
      page.css('img.product-card-image').each do |scrape|
        page.css('a.product-card-image-link').each do |scrape2|
          #      [      product       ,     link       ]
          csv << [scrape['alt'][0..-7], scrape2['href']]
          # NOTE that scrape['alt'][0..-7] and scrape2['href'] are already strings
          # so you don't need to use "#{ }"
        end
      end
    end
    

    旁注:Ruby 2.0.0 不需要require "rubygems" 这一行

    如果您使用 CSV,我强烈建议您使用 James Edward Gray II 的 faster_csv gem。在此处查看使用示例:https://github.com/JEG2/faster_csv/blob/master/examples/csv_writing.rb

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多