7

構築したサイトをクロールし、JavaScriptファイルが含まれているかどうかを確認するPhantomJSアプリを作成しました。JavaScriptはGoogleに似ており、一部のインラインコードが別のJSファイルに読み込まれます。アプリは他のJSファイルを検索するため、Phantomを使用しました。

期待される結果は何ですか?

コンソール出力は、大量のURLを読み取り、スクリプトがロードされているかどうかを通知する必要があります。

本当に何が起こっているのですか?

コンソール出力は、約50のリクエストに対して期待どおりに読み取られ、次のエラーを吐き出し始めます。

2013-02-21T10:01:23 [FATAL] QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe
QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files

これは、ページを開いてスクリプトを検索するコードのブロックです。

page.open(url, function (status) {
    console.log(YELLOW, url, status, CLEAR);
    var found =  page.evaluate(function () {
      if (document.querySelectorAll("script[src='***']").length) {
        return true;
      } else { return false; }
    });

    if (found) {
      console.log(GREEN, 'JavaScript found on', url, CLEAR);
    } else {
      console.log(RED, 'JavaScript not found on', url, CLEAR);
    }
    self.crawledURLs[url] = true;
    self.crawlURLs(self.getAllLinks(page), depth-1);
  });

クロールされたURLオブジェクトは、私がすでにクロールしたURLのオブジェクトにすぎません。scrollURLs関数は、getAllLinks関数からのリンクを通過し、クローラーが開始したドメインのベースドメインを持つすべてのリンクでopen関数を呼び出します。

編集

コードの最後のブロックを次のように変更しましたが、それでも同じ問題が発生します。ファイルにpage.close()を追加しました。

if (!found) {
  console.log(RED, 'JavaScript not found on', url, CLEAR);
}
self.crawledURLs[url] = true;
var links = self.getAllLinks(page);
page.close();
self.crawlURLs(links, depth-1);
4

3 に答える 3

6

ドキュメントから:

いくつかの技術的な制限により、Web ページ オブジェクトが完全にガベージ コレクションされない場合があります。これは、同じオブジェクトが何度も使用されている場合によく発生します。

close()解決策は、Web ページ オブジェクトを (page多くの場合) 適切なタイミングで明示的に呼び出すことです。

follow.jsなどの一部の例では、明示的に閉じる複数のページ オブジェクトを示しています。

于 2013-02-21T16:02:55.110 に答える
4

オープン ファイルの制限。

ファイルを適切に閉じても、このエラーが発生する可能性があります。

インターネットを精査した後、1 つのプロセスで開くことができるファイル数の制限を増やす必要があることがわかりました。私の場合、数百から数千ページの PDF を生成していました。

実行しているシステムに基づいてこの設定を調整する方法はいくつかありますが、 Ubuntuサーバーでうまくいった方法は次のとおりです。

の末尾に次を追加します/etc/security/limits.conf

# Sets the open file maximum here.
# Generating large PDFs hits the default ceiling (1024) quickly. 
*    hard nofile 65535
*    soft nofile 65535
root hard nofile 65535 # Need these two lines because the wildcards (above)
root soft nofile 65535 # are not applied to the root user as well.

ulimitコマンドの適切なリファレンスは、ここにあります。

それが何人かの人々を正しい軌道に乗せることを願っています。

于 2015-08-06T17:30:48.383 に答える
0

Ruby プログラムで複数のスレッドを実行しているときに、このエラーが発生しました。私は Capybara-poltergeist で phantomjs を実行していましたが、各スレッドはページにアクセスして同じ CSV ファイルを開いて書き込みを行っていました。

Mutexクラスを使用して修正できました。

lock = Mutex.new
lock.synchronize do
    CSV.open("reservations.csv", "w") do |file|
        file << ["Status","Name","Res-Code","LS-Num","Check-in","Check-out","Talk-URL"]
          $status.length.times do |i|
              file << [$status[i],$guest_name[i],$reservation_code[i],$listing_number[i],$check_in[i],$check_out[i], $talk_url[i]]
          end
        end
        puts "#{user.email} PAGE NUMBER ##{p+1} WRITTEN TO CSV"
    end
end
于 2016-02-20T06:38:20.983 に答える