Mechanize的getaddrinfo错误

时间:2012-11-01 22:09:30

标签: ruby mechanize mechanize-ruby

我写了一个脚本,它将遍历我们数据库中的所有客户,验证他们的网站URL是否有效,并尝试在他们的主页上找到推特链接。我们有超过10,000个网址需要验证。如果验证了网址的一小部分,我们就会开始为每个网址获取getaddrinfo错误。

以下是抓取单个网址的代码副本:

def scrape_url(url) 
  url_found = false 
  twitter_name = nil 

  begin 
    agent = Mechanize.new do |a| 
      a.follow_meta_refresh = true 
    end 

    agent.get(normalize_url(url)) do |page| 
      url_found = true 
      twitter_name = find_twitter_name(page) 
    end 

    @err << "[#{@current_record}] SUCCESS\n" 
  rescue Exception => e 
    @err << "[#{@current_record}] ERROR (#{url}): " 
    @err << e.message 
    @err << "\n" 
  end 

  [url_found, twitter_name] 
end

注意:我还运行了此代码的一个版本,该版本创建了一个在所有scrape_url调用中共享的Mechanize实例。它以完全相同的方式失败了。

当我在EC2上运行它时,它几乎完全通过1,000个网址,然后为剩余的9,000 +返回此错误:

getaddrinfo: Temporary failure in name resolution

请注意,我已尝试使用亚马逊的DNS服务器和谷歌的DNS服务器,认为这可能是合法的DNS问题。在这两种情况下我都得到了完全相同的结果。

然后,我尝试在我当地的MacBook Pro上运行它。在为剩余的记录返回此错误之前,它只通过了大约250个:

getaddrinfo: nodename nor servname provided, or not known

有谁知道如何让脚本通过所有记录?

2 个答案:

答案 0 :(得分:8)

我找到了解决方案。 Mechanize正在打开连接并依靠GC来清理它们。在某一点之后,有足够的开放连接,无法建立额外的出站连接来进行DNS查找。这是导致它工作的代码:

agent = Mechanize.new do |a| 
  a.follow_meta_refresh = true
  a.keep_alive = false
end

通过将keep_alive设置为false,立即关闭并清除连接。

答案 1 :(得分:0)

看看这是否有帮助:

agent.history.max_size = 10

它将使历史记录不会使用太多内存