Mechanize的getaddrinfo错误

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

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

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 < e @err << "[#{@current_record}] ERROR (#{url}): " @err << e.message @err << "\n" end [url_found, twitter_name] end 

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

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

 getaddrinfo: Temporary failure in name resolution 

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

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

 getaddrinfo: nodename nor servname provided, or not known 

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

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

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

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

看看这是否有帮助:

 agent.history.max_size = 10 

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