基本的なアイデア
原点:マスター:ウィキペディアの特定のカテゴリ(航空機運送業者(キー)ページなど、リンクのタイトル属性にキー(航空機キャリア)を含むすべてのターゲットを見つけて、キューにrawってキューに追加します。この方法では、ページのコードと写真をつかみながら、他のすべてのWebページのアドレスを採用しています。このタスクを完了するためのクラスの幅の横断。
Idea 2(Origin:CAT):分類によるクロール。ウィキペディアでは、カテゴリがカテゴリから始まることに注意してください。ウィキペディアには優れたドキュメント構造があるため、あらゆるカテゴリから簡単に開始し、その下のすべてのカテゴリを常にクロールすることができます。このアルゴリズムは、分類ページのサブカテゴリ化を抽出し、その下のすべてのページを並行してつかみます。高速で分類構造を保存できますが、実際には多くの重複ページがありますが、これは後の段階でスクリプトを書くことで簡単に処理できます。
ライブラリの選択
私はJSDOMを使用し始めました。私はそれが強力であると感じましたが、それはまた非常に「重い」ものでした。最も深刻なことは、説明文書が十分ではなかったことです。私はその利点しか言及していませんでしたが、包括的な説明はありませんでした。したがって、Cheerioに変更すると、軽量で、比較的完全な機能があります。少なくとも、一目で包括的なコンセプトを持つことができます。実際、それを行った後、私はライブラリがまったく必要ではないことに気付きました。私は図書館で少し規則性を書きました。
キーポイント
グローバル変数設定:
var regkey = ['Aircraft Carrier'、 'Aircraft Carrier'、 'aircraft Carrier']; //キーワードがリンクに含まれている場合、それはターゲットvar allkeys = []です。 //リンクのタイトルはページ識別子でもあり、varキーの繰り返しクロール= ['カテゴリ:%e8%88%aa%e7%a9%ba%e6%af%8d%e8%88%b0']; //キューを待っている、ページを開始します
画像ダウンロード
リクエストライブラリのストリーミング操作を使用して、各ダウンロード操作を閉鎖にします。非同期操作の副作用の可能性に注意してください。さらに、画像名をリセットする必要があります。最初は元の名前を取りました。何らかの理由で、いくつかの画像が明らかに存在しますが、表示することはできません。また、SRCSET属性をクリアする必要があります。そうしないと、元の表面を表示できません。
$ = cheer.load(downhtml); var rshtml = $ .html(); var imgs = $( '#bodycontent .image'); //写真は(IMGのIMG){if(typeof imgs [img] .attribs === 'undefined' || typeof imgs [img] .attribs.href == '未定義'){continue;} //リンクの下にある画像であり、リンクが存在しない{var pipuurl = skipの構造であるif(typeof imgs [img] .attribs === type)のために変更されます。 imgs [img] .children [0] .attribs.src; //画像アドレスvar dirs = picurl.split( '。'); var filename = beadir+uuid.v1()+'。'+dirs [dir.length -1]; // request( "https:"+picurl).pipe(fs.createwritestream( 'pages/'+filename)); // rshtml = rshtml.replace(picurl、filename)をダウンロードしてください。 //ローカルパスを交換// console.log(picurl); }}幅の優先度トラバーサル
最初は、非同期性の概念を完全に理解しておらず、ループでそれをしました。私は、約束を使用することはすでに同期に変換されていると思いましたが、実際、それは約束に引き継がれた操作が整然とした方法で実行されることを保証するだけであり、これらの操作は他の操作で注文することはできません!たとえば、次のコードが正しくありません。
var keys = ['aircraft carrier']; var key = keys.shift(); while(key){data.get({url:ecodeuri(key)、qs:null})。 //(2)}上記の操作は正常ですが、実際には(2)は(1)の間に実行されます!何をするか?
この問題を解決するために再帰を使用しました。次の例コード:
var key = keys.shift();(function dent(key){data.get({url:key、qs:null})。then(function(downhtml){... keys.push(href); ... key = keys.shift(); if(key){key){denxt(key); })})(鍵);定期的なクリーニング
正規表現を使用して役に立たないページコードをきれいにします。これは、処理する必要がある多くのパターンがあるため、均一に処理するためのループを書きました。
var regs = [/<link rel =/"styleSheet/" href =/"?[^//"]*/">/g、/<script>?[^<]*<// script>/g、/<style>?[^<]*<// style>/g、/<a?[^>]*>/g、/</a>/g、/scset =(/"/"/"/"/"/"] regs.foreach(function(rs){var mactches = rshtml.match(rs); for(var i = 0; i <mactches.length; i ++){rshtml = rshtml.replace(mactches [i]、mactches [i] .indexof( 'styleheet') href = "wiki '+(i+1)+'。css" ':' ');ランニング効果
wiki中国語ではFQが必要です。私はそれを試して、航空機のキャリア分類をつかみました。操作中に、約300の関連リンクを見つけました(分類ページを含む。有効なリンクのみを使用して、ダウンロードしませんでした)。最後に、209を正しくダウンロードしました。いくつかのエラーリンクを手動でテストし、それらが無効なリンクであることがわかりました。エントリがまだ確立されていないことを示しました。プロセス全体には約15分未満かかりました。圧縮後、それはほぼ30 mで、効果はかなり良かったと感じました。
ソースコード
https://github.com/zhoutk/wikispider
まとめ
昨夜タスクを基本的に完了した頃には、Idea 1は比較的正確なコンテンツでページをクロールでき、ページは繰り返されませんが、クロール効率は高くなく、分類された情報を正確に取得できません。 Idea 2は、ウィキペディアによると、カテゴリでファイルを自動的にクロールおよび保存し、非常に効率的です(実際の測定、rawう[軍艦]、合計6,000ページ近くのrawい、約50分かかり、100ページ以上が1分あたりクロールできます)。
最大の利益は、非同期プログラミングの全体的なプロセス制御を深く理解することです。