3

フロントエンドとしてRuby、RailsでWebクローラーを構築しています。Nokogiriの上に構築されたMechanizeを使用しています。私はすでに Web ページをクロールするソリューションを実装していますが、1 回の実行で 20 万の Web サイトをクロールできるようにしたいと考えており、完了するまで何時間も待つよりも良い方法があることを知っています。複雑になりすぎずに並列リクエストを起動することで、最高のパフォーマンスを達成できるようにしたいと考えています。私はスレッディングとその制限について何も知らないので、誰かがこれを行う方法を学ぶことができる場所を指摘したい場合、または少なくとも私が何をすべきかを教えてくれる場合は、クローラーの実行中にサーバーを人質にしないでください。探している。データベースとファイルに書き込むことを覚えておいてください(おそらく、クロールが完了したらデータベースからエクスポートでき、ファイルに直接書き込むことはできません)。ありがとう。

注:ここSOにも同様の質問がありますが、数年前のもので、おそらく人々は今とは違ったやり方をしていて、非常に複雑に見えます。

4

3 に答える 3

5

TyphoeusとHydraの使用を見てください。URLを並行して処理するのが簡単になります。

各ページから特別なデータを要求する必要がない限り、Mechanizeを使用する必要はありません。通常のクローラーの場合、Mechanizeのオーバーヘッドや追加機能なしで、Open::URIとNokogiriを使用して本体を取得して解析できます。目的に応じて、Open :: URIの代わりにTyphoeusを使用し、Hydraにスレッド管理を処理させます。

200kのWebサイトをクロールすると、一度にすべてを実行しようとすると、帯域幅が飽和することを忘れないでください。それはあなたのRailsサイトを利用できなくするでしょう、それであなたはあなたの要求を絞る必要があります。そして、それはあなたが数時間(または何時間も)それらをしなければならないことを意味します。ここでサイトをオンラインに保つほど、速度は重要ではありません。おそらく、クローラーをRailsサーバーとは別のマシンに配置し、データベースにそれらを結び付けさせます。

クロールしているサイトのURLを含むテーブルまたはファイルを作成します。URLを編集/管理するためのフォームをまとめられるように、この表をお勧めします。次のようなものを追跡する必要があります。

  • URLが最後にクロールされたとき。(日付時刻)
  • 特定のURLをクロールする必要があるかどうか(ブール値または文字1
  • URL(Stringまたはvar char [1024]で問題ありません)。これは一意のキーである必要があります。
  • そのURLが現在クロールされているかどうか(ブール値またはchar 1)。これは、すべてのレコードの実行の開始時にクリアされ、スパイダーがそのページをロードするときに設定され、残されます。
  • そのサイトをいつ実行してもよいかを示すフィールド。
  • そのサイトを実行しても問題がない時間を示すフィールド。

最後の2つは重要です。電力が不足している小さなサイトをクロールして、その接続を切断したくありません。それは禁止されるための素晴らしい方法です。

クロール中に遭遇したリンクから収集された特定のサイトをチェックするための次のURLである別のテーブルを作成します。セッションデータとパラメータを含むURLを、一意性をテストするために使用できるものに減らすための正規化ルーチンを考え出す必要があります。この新しいテーブルでは、URLを一意にして、ループに陥ったり、異なるパラメーターを使用して同じページを追加し続けたりしないようにする必要があります。

リダイレクトとDNS名はサイト内で異なる可能性があり、コンテンツを生成する人々は異なるホスト名を使用している可能性があるため、「get」URLではなくリダイレ​​クト後に取得される実際のランディングURLに注意を払うことをお勧めします。同様に、ヘッドブロックでメタリダイレクトを探して、それに従うこともできます。これらはあなたが書きたいことをすることの特に苛立たしい側面です。

新しいURLに遭遇したら、それらが既存のURLであるかどうかを確認します。これにより、それらをフォローした場合、そのサイトを離れることになります。その場合は、それらをURLテーブルに追加しないでください。

正しいファイルを見つけるには、とにかくデータベース検索を行う必要があるため、データベース情報をファイルに書き込むことはおそらく役に立ちません。必要なものをフィールドに保存して、直接リクエストするだけです。200K行はデータベースには何もありません。

サイトの「スパイダー」ルールに注意してください。サイトがデータを取得するためのAPIを提供している場合は、クロールする代わりにそれを使用してください。

于 2012-09-24T19:32:05.963 に答える
3

私はRubyの専門家ではありませんが、他のプログラミング言語での経験に基づいたアイデアと回答を以下

に示します。A.WebサーバーまたはRubyアプリケーションを実行している環境のスレッドモデルを理解する必要があります。
たとえば、TomcatというWebサーバーを使用していて、開くスレッドの数を構成できます。
もちろん、これはOSで可能なスレッドの数を超えることはできません。

B.さらに、「クロール」する必要があるため、おそらくファイル(つまり、Linuxのファイル記述子)を操作する必要があり、これらは限られたリソースであることを忘れないでください。
たとえばLinuxでは、ulimitを使用してファイル記述子の制限を構成できます。

C.スレッドのプールを用意することを強くお勧めします(Rubyにはこのためのフレームワークがあると確信していますこれは、グーグルで調べたときに思いついたものです)。
スレッドプールを使用するとは、スレッドを使用しているが、スレッドを開いたり閉じたりするのではなく、スレッドのグループがあり、共有データ構造からジョブを抽出して実行することを意味します。
たとえば、ジョブごとに次の擬似コードを実行することができ
ます。1.Webページを解析します
。2。リンクごとに実行します
。2.1。URLを使用してジョブを作成します。
2.2ジョブをキューに配置する(スレッドプールスレッドが機能するため)

また、クラスタリング(たとえば、クラウド上の複数のマシン)を使用し、スケーラブルなソリューションを開発することを真剣に検討します。
これは、クラスターノード間に何らかの共有データ構造(データベースまたはNoSQL DBなど)があり、ワーカースレッドがジョブを抽出し、このクラスター単位(クラウド単位)の共有データ構造に新しいジョブを配置することを意味します。また、ここで役立つmap-reduce
パターン について読んで 、RubyでHadoopを使用することをお勧めします(ここにリンクを参照してください)。 繰り返しになりますが、私はルビーの専門家ではありませんが、使用している他のコンピューター言語で問題が発生しました。 私はあなたにいくつかのヒントと読み物を与えたことを望みます。幸運を!




于 2012-09-22T18:56:52.507 に答える
0

http://anemone.rubyforge.org/index.htmlを確認してください

それはあなたのニーズに合うかもしれないと思います、そうでなければあなたはそれのソースコードから多くを学ぶことができるはずです。

于 2012-09-22T19:02:23.870 に答える