我在下面设置了一个Nokogiri刮刀。一切都很好,只是很慢。我一直在研究如何让它更快,并遇到了使用线程、将它移动到后台进程、保存到数据库并缓存它的问题,我只是不确定该走什么路线,也不确定从哪里开始。建议或指导将不胜感激。您可以在上查看实时版本http://clstorycloud.com抓取器抓取来自同一域上不同博客的博客图像和帖子,目前正在实时抓取。
型号
class Photocloud < ActiveRecord::Base
attr_reader :start_urls
attr_accessor :images, :paths
def initialize(start_urls)
@start_urls = start_urls
@paths = []
@images = []
end
def scrape
start_urls.each do |start_url|
blog = Nokogiri::HTML(open(start_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
查看
<div id="container" class="container">
<% @paths.zip(@images).each do |url, img|%>
<div class="item tranz ">
<a href="<%= url %>" target="_blank"><img src="http://www.cltampa.com<%= img %>"></a>
</div>
<% end %>
</div>
</div>
控制器
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]
scraper = Photocloud.new(start_urls)
scraper.scrape
@images = scraper.images
@paths = scraper.paths
end
我建议使用斑疹伤寒进行pararell请求。
现在,你的scrape
方法必须在开始下一个请求之前完成一个请求,如果你做pararell请求(一次发送所有请求,而不是一个接一个地发送),你可以优化它。
使用typheous
,您的代码看起来像:
hydra = Typhoeus::Hydra.hydra
start_urls.each do |start_url|
# Build a request object representing the actual request you want to send and add it to the queue.
hydra.queue(Typhoeus::Request.new(start_url))
end
# Then, run all the queued request in pararell.
hydra.run
# Then, you can get all requests response like this
responses = requests.map do |request|
request.response.body
# Any other code here
end
使用此方法,您可以优化刮刀。假设您有10个请求需要处理,每个请求需要10秒。采用实际方法,总处理时间将为100秒。通过在pararell中发送所有请求,总处理时间将仅为10。
你可以在这里找到关于typheous
的所有文档。要直接进入关于pararell请求的部分,请单击此处。