0

Nokogiri 在控制台中对我来说工作得很好,但如果我把它放在任何地方......模型、视图或控制器,它就会超时。

我想以两种方式中的一种使用它...

控制器

def show
  @design = Design.find(params[:id])
  doc = Nokogiri::HTML(open(design_url(@design)))
  images = doc.css('.well img') ? doc.css('.well img').map{ |i| i['src'] } : []
end

或者...

模型

def first_image
  doc = Nokogiri::HTML(open("http://localhost:3000/blog/#{self.id}"))
  image = doc.css('.well img')[0] ? doc.css('.well img')[0]['src'] : nil
  self.update_attribute(:photo_url, image)
end

两者都会导致超时,尽管它们在控制台中运行良好。

4

3 回答 3

2

当您从控制台运行 Nokogiri 代码时,您将在localhost:3000. 因此,有两个实例正在运行:一个拨打电话(您的控制台),一个接听电话(您的服务器)

当您从应用程序中运行它时,您正在引用应用程序本身,这会导致无限循环,因为没有可用资源来响应您的调用(该资源就是发出调用的资源!)。因此,您需要使用 Unicorn 之类的东西运行多个实例(或者只是在不同端口上的另一个 localhost 实例),并且您至少需要其中一个实例才能自由地回答 Nokogiri 请求。

如果您打算在生产中运行它,只需知道此设置将需要可用资源来响应 Nokogiri 请求,因此您实际上每次调用都会占用 2 个实例。因此,如果您有 4 个实例并且所有 4 个实例碰巧同时进行了调用,那么您的整个应用程序就搞砸了。一次只有 1 或 2 个调用,您可能会经历相当严重的退化......

于 2013-10-08T23:06:17.537 回答
1

我不确定超时的默认值。但是您可以指定一些超时值,如下所示。

require 'net/http'

http = Net::HTTP.new('localhost')
http.open_timeout = 100
http.read_timeout = 100
Nokogiri.parse(http.get("/blog/#{self.id}").body)

最后你可以找到问题所在,因为你可以控制超时值。

于 2013-10-04T20:42:44.937 回答
-1

所以,在泰勒的建议下,我深入研究了我正在做的事情。由于 ckeditor 与图像断开连接,由于载波和 S3,我无法直接从上传者那里获得任何信息(至少在我看来是这样)。

相反,我坚持使用 nokogiri,而且效果很好。我意识到我实际上用这个open()命令做了什么,这是完全没有必要的。Nokogiri 解析 HTML。我可以给它 HTML 格式的@design.content!呃,就我而言。

所以,这就是我抓取自己网站的方式,以获取与博客条目相关联的图像:

设计控制器.rb

def create
  params[:design][:photo_url] = Nokogiri::HTML(params[:design][:content]).css('img').map{ |i| i['src']}[0]
  @design = Design.new(params[:design])
  if @design.save
    flash[:success] = "Design created"
    redirect_to designs_url
  else
    render 'designs/new'
  end
end

def show
  @design = Design.find(params[:id])
  @categories = @design.categories
  @tags = @categories.map {|c| c.name}
  @related = Design.joins(:categories).where('categories.name' => @tags).reject {|d| d.id == @design.id}.uniq
  set_meta_tags og: {
    title: @design.name,
    type: 'article',
    url: design_url(@design),
    image: Nokogiri::HTML(@design.content).css('img').map{ |i| i['src']},
    article: {
      published_time: @design.published_at.to_datetime,
      modified_time: @design.updated_at.to_datetime,
      author: 'Alphabetic Design',
      section: 'Designs',
      tag: @tags
    }
  }
end

更新操作与创建操作具有相同的 Nokogiri 代码。

现在我正在看它似乎有点明显,大声笑。我在这件事上停留的时间比我想承认的要长……

于 2013-10-09T08:59:48.907 回答