【问题标题】:Nokogiri Scraping In RailsNokogiri 在 Rails 中刮擦
【发布时间】:2015-02-13 22:41:58
【问题描述】:

所以我的索引操作中有这段代码,很想把它移到模型中,只是对如何做有点困惑。

原码

  def index
    urls = %w[http://cltampa.com/blogs/potlikker http://cltampa.com/blogs/artbreaker http://cltampa.com/blogs/politicalanimals http://cltampa.com/blogs/earbuds http://cltampa.com/blogs/dailyloaf http://cltampa.com/blogs/bedpost]
    @final_images = []
    @final_urls = []
    
    urls.each do |url|
      blog = Nokogiri::HTML(open(url)) 
      images = blog.xpath('//*[@class="postBody"]/div[1]//img/@src')
      images.each do |image|
        @final_images << image
      end
      
      story_path = blog.xpath('//*[@class="postTitle"]/a/@href')
      story_path.each do |path|
        @final_urls << path
      end
    end  
  end

我在我的模型中测试了这段代码,它适用于一个 url,只是不确定如何像原始代码一样集成所有 url。

新代码

型号

class Photocloud < ActiveRecord::Base

  attr_reader :url, :data

  def initialize(url)
    @url = url
  end

  def data
    @data ||= Nokogiri::HTML(open(url))
  end

  def get_elements(path)
    data.xpath(path)
  end

end

控制器

def index 
  @scraper = Photocloud.new('http://cltampa.com/blogs/artbreaker')
  @photos = @scraper.get_elements('//*[@class="postBody"]/div[1]//img/@src')
  @story_urls = @scraper.get_elements('//*[@class="postBody"]/div[1]//img/@src')
end

我的主要问题是如何初始化多个 url 并像我的原始代码一样循环它们。我尝试过不同的事情,但感觉就像碰壁了。我需要将它们保存到数据库中,但想先让它工作。非常感谢任何帮助。

更新的控制器 - WIP

  def index
    start_urls = %w[http://cltampa.com/blogs/potlikker 
      http://cltampa.com/blogs/artbreaker 
      http://cltampa.com/blogs/politicalanimals 
      http://cltampa.com/blogs/earbuds 
      http://cltampa.com/blogs/dailyloaf 
      http://cltampa.com/blogs/bedpost]
    @scraper = Photocloud.new(start_urls)
    @images = 
    @paths = 
  end

这部分需要一些帮助...

【问题讨论】:

    标签: ruby-on-rails ruby nokogiri


    【解决方案1】:

    您似乎没有将抓取的图像和路径保存到数据库,因此Photocloud 不需要从ActiveRecord::Base 继承 - 它可以只是一个普通的旧 ruby​​ 对象 (PORO):

    class Photocloud
      attr_reader :start_urls
      attr_accessor :images, :paths
    
      def initialize(start_urls)
        @start_urls = start_urls
        @images = []
        @paths = []
      end
    
      def scrape
        start_urls.each do |start_url|
          blog = Nokogiri::HTML(open(url))
          scrape_images(blog)
          scrape_paths(blog)
        end
      end
    
      private
      def scrape_images(blog)
        images = blog.xpath('//*[@class="postBody"]/div[1]//img/@src')
        images.each do |image|
          images << image
        end
      end
    
      def scrape_paths(blog)      
        story_path = blog.xpath('//*[@class="postTitle"]/a/@href')
        story_path.each do |path|
          paths << path
        end
      end
    end
    

    在控制器中:

    scraper = Photocloud.new(start_urls)
    scraper.scrape
    @images = scraper.images
    @paths = scraper.paths
    

    当然,这只是构建代码的一种可能性。

    【讨论】:

    • 嗨@Andrius,感谢您的帮助,非常感谢。我在上面的代码中添加了一个更新的控制器部分,你有没有机会看看并给出一些见解?尝试根据您向我展示的内容进行设置。
    • 再次感谢您,由于某种原因,在更新控制器后,我的照片得到了一个空数组,但我正在努力。
    • 我必须更新私有方法才能使用实例变量,现在它工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 2021-09-06
    • 2014-08-10
    • 1970-01-01
    • 2022-01-02
    • 2021-05-06
    相关资源
    最近更新 更多