7

私は、データベース内のすべての顧客を調べ、顧客のWebサイトのURLが機能することを確認し、顧客のホームページでTwitterリンクを見つけようとするスクリプトを作成しました。確認するURLは10,000を少し超えています。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 << "[#{@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のURLを通過し、残りの9,000以上に対してこのエラーが返されます。

getaddrinfo: Temporary failure in name resolution

注:AmazonのDNSサーバーとGoogleのDNSサーバーの両方を使用してみましたが、これは正当なDNSの問題である可能性があると考えています。どちらの場合もまったく同じ結果が得られました。

次に、ローカルのMacBookProで実行してみました。残りのレコードに対してこのエラーを返す前に、約250を通過しただけです。

getaddrinfo: nodename nor servname provided, or not known

スクリプトを取得してすべてのレコードを処理する方法を知っている人はいますか?

4

2 に答える 2

10

私は解決策を見つけました。Mechanizeは接続を開いたままにし、GCに依存してそれらをクリーンアップしていました。ある時点以降、DNSルックアップを実行するための追加のアウトバウンド接続を確立できなくなるほど、十分なオープン接続がありました。これが機能する原因となったコードは次のとおりです。

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

keep_aliveをfalseに設定すると、接続はすぐに閉じられ、クリーンアップされます。

于 2012-11-03T20:59:55.107 に答える
0

これが役立つかどうかを確認します。

agent.history.max_size = 10

履歴がメモリを使いすぎないようにします

于 2012-11-02T00:07:43.277 に答える