エントリから刑務所までのクローラー(5)-マルチスレッドクローラーと一般的な検索アルゴリズム

記事の内容は「Pythonクローラー開発」からです

5.1マルチスレッドクローラー

5.1.1マルチスレッドの利点

リクエストと正規表現をマスターした後、実際にいくつかの単純なURLのクロールを開始できます。
ただし、現時点では、クローラーにはプロセスとスレッドが1つしかないため、シングルスレッドクローラーと呼ばれます。シングルスレッドクローラーは一度に1ページにしかアクセスせず、コンピューターのネットワーク帯域幅を十分に活用できません。ページはせいぜい数百KBしかないため、クローラーがページをクロールすると、余分なネットワーク速度と、要求を開始してからソースコードを取得するまでの時間が無駄になります。クローラーが同時に10ページにアクセスできる場合、クロール速度の10倍に相当します。この目的を達成するには、マルチスレッド技術を使用する必要があります。

Python言語には、グローバルインタープリターロック(GIL)があります。これにより、Pythonのマルチスレッドは疑似マルチスレッドである、つまり本質的にスレッドであるという事実につながりますが、このスレッドはそれぞれのことを数ミリ秒だけ実行し、数ミリ秒後にシーンを保存し、その他のことを実行します数ミリ秒後、数ミリ秒後に他のことを行います。1ラウンド後、最初のことに戻り、シーンを復元してさらに数ミリ秒を実行し、変更を続けます...マイクロレベルの単一スレッドマクロレベルで同時にいくつかのことを行うようなものです。このメカニズムは、I / O(入力/出力、入力/出力)を多用する操作にはほとんど影響しませんが、CPUを多用する操作では、CPUのコアを1つしか使用できないため、パフォーマンスに非常に悪影響を及ぼします。大きな影響。したがって、計算量の多いプログラムになると、複数のプロセスを使用する必要があります。Pythonの複数のプロセスはGILの影響を受けません。クローラーはI/Oを多用するプログラムであるため、マルチスレッドを使用するとクロールの効率を大幅に向上させることができます。

5.1.2マルチプロセッシングライブラリ:マルチプロセッシング

マルチプロセッシング自体は、マルチプロセッシングに関連する操作を処理するPythonのマルチプロセッシングライブラリです。ただし、プロセスとプロセスはメモリとスタックリソースを直接共有できず、新しいプロセスを開始するオーバーヘッドはスレッドのオーバーヘッドよりもはるかに大きいため、マルチスレッドを使用してクロールする方が、マルチプロセスを使用するよりも多くの利点があります。

マルチプロセッシングの下にダミーモジュールがあり、Pythonスレッドがさまざまなマルチプロセッシングメソッドを使用できるようにします。
ダミーの下にPoolクラスがあり、これはスレッドプールを実装するために使用されます。
このスレッドプールには、スレッドプール内のすべてのスレッドが関数を「同時に」実行できるようにするmap()メソッドがあります。

例:
forループについて学習した後

for i in range(10):
	print(i*i)

もちろんこの書き方でも結果は出ますが、コードは一つずつ計算されており、効率は高くありません。また、マルチスレッドテクノロジーを使用する場合は、コードで同時に多くの数値の2乗を計算するようにします。次のことを実現するには、multiprocessing.dummyを使用する必要があります。

マルチスレッドの使用例:

from multiprocessing.dummy import Pool
def cal_pow(num):
    return num*num
pool=Pool(3)
num=[x for x in range(10)]
result=pool.map(cal_pow,num)
print('{}'.format(result))

上記のコードでは、最初に2乗を計算する関数が定義され、次に3つのスレッドを持つスレッドプールが初期化されます。これらの3つのスレッドは、10の数値の二乗を計算する役割を果たします。最初に手元の数値の計算を終了した人は、次の数値を取得し、すべての数値が計算されるまで計算を続行します。

この例では、スレッドプールのmap()メソッドは2つのパラメーターを取ります。最初のパラメーターは関数名で、2番目のパラメーターはリストです。注:最初のパラメーターは関数の名前であり、括弧で囲むことはできません2番目のパラメーターは反復可能オブジェクトであり、反復可能オブジェクトの各要素は、関数clac_power2()によってパラメーターとして受け取られます。リストに加えて、タプル、セット、またはディクショナリをmap()の2番目の引数として使用できます。

5.1.3マルチスレッドクローラーの開発

クローラーはI/Oを多用する操作であるため、特にWebページのソースコードを要求する場合、開発に単一のスレッドを使用すると、Webページが戻るのを待つのに多くの時間が無駄になり、マルチスレッドを適用します。クローラーへのテクノロジーは、クローラーの効率を大幅に向上させることができます。例として。洗濯機で洗濯するのに50分、やかんでお湯を沸かすのに15分、言葉を覚えるのに1時間かかります。洗濯機が最初に衣類を洗うのを待ってから、衣類を洗った後に水を沸騰させ、次に水が沸騰した後に言葉を唱えると、合計125分かかります。

しかし、別の見方をすれば、全体論的な観点からすると、3つのことが同時に実行される可能性があります。突然2人に分かれた場合、そのうちの1人が洗濯機に服を入れて洗濯機を待つ責任があります。もう一方は水を燃やして水が沸騰するのを待つ責任があり、あなたは自分で言葉を覚える必要があります。水が沸騰すると、水を沸騰させるクローンが最初に消えます。洗濯機が衣類の洗濯を終えると、洗濯を担当していたクローンが消えます。最後に、あなたは自分で単語を覚えました。同時に3つのことを完了するのに60分しかかかりません。

もちろん、あなたは確かに上記の例が実際の生活の状況ではないことに気付くでしょう。実際には、誰も分離されません。実生活の状況では、人々が言葉を暗唱するとき、彼らは言葉を暗記することに集中します。水が沸騰すると、やかんは思い出させるためにビープ音を鳴らします。したがって、通知されたときに対応するアクションを実行することをお勧めします。毎分チェックする必要はありません。上記の2つの違いは、実際にはマルチスレッドモデルとイベント駆動型非同期モデルの違いです。このセクションでは、マルチスレッド操作について説明します。非同期操作を使用するクローラーフレームワークについては後で説明します。ここで、操作するアクションの数が多くない場合、2つの方法のパフォーマンスに違いはありませんが、アクションの数が大幅に増えると、マルチスレッドの効率の向上は低下し、シングルよりもさらに悪くなることを覚えておいてください。 -スレッド。そしてその時、非同期操作だけが問題の解決策です。

次の2つのコードを使用して、bdホームページをクロールするためのシングルスレッドクローラーとマルチスレッドクローラーのパフォーマンスの違いを比較します。画像の説明を追加してください
実行結果から、1つのスレッドに約16.2秒、5つのスレッドに約3.5がかかることがわかります。 sであり、時間はシングルスレッドの5倍です。約3分の1です。その時から、5つのスレッドが「同時に実行されている」効果も確認できます。ただし、スレッドプールの設定が大きいほど良いという意味ではありません。上記の結果から、5スレッドの実行時間は、実際には1スレッドの実行時間の5分の1強であることがわかります。この余分なポイントは、実際にはスレッド切り替えの時間です。これは、Pythonのマルチスレッドがまだ微視的にシリアルであるという側面からも反映されています。したがって、スレッドプールの設定が大きすぎると、スレッドの切り替えによって発生するオーバーヘッドによって、マルチスレッドによるパフォーマンスの向上が相殺される可能性があります。スレッドプールのサイズは実際の状況に応じて決定する必要があり、正確なデータはありません。読者は、さまざまなサイズを設定して、特定のアプリケーションシナリオでテストおよび比較し、最適なデータを見つけることができます。

5.2クローラーの一般的な検索アルゴリズム

5.2.1深さ優先探索

オンライン教育ウェブサイトのコース分類では、上記のコース情報をクロールする必要があります。ホームページから始めて、コースには、言語に応じてPython、Node.js、Golangなどのいくつかの主要なカテゴリがあります。クローラー、Django、Pythonでの機械学習など、各主要カテゴリには多くのコースがあります。各コースは多くの時間に分かれています。

深さ優先探索の場合、クロールルートを図に示します(小さいものから大きいものへのシリアル番号)
画像の説明を追加してください

5.2.2幅優先探索

シーケンスは次のとおりです。
画像の説明を追加してください

5.2.3アルゴリズムの選択

たとえば、Webサイト上のすべてのレストラン情報と各レストランの注文情報をクロールします。深さ優先アルゴリズムが使用されていると仮定すると、最初に特定のリンクからレストランAにクロールし、次にレストランAの注文情報をすぐにクロールします。全国に数十万のレストランがあるため、すべてを登るのに12時間かかる場合があります。これがもたらす問題は、レストランAの注文量が午前8時に増加する可能性があるのに対し、レストランBの注文量は午後8時に増加する可能性があることです。彼らの注文量は12時間遅れています。そして人気のあるレストランにとって、12時間は何百万もの違いを生む可能性があります。このように、データ分析を行う場合、12時間の時差があるため、2つのレストランAとBの販売実績を比較することは困難です。レストランの数は、注文のサイズに比べてはるかに少なく変化しています。したがって、幅優先探索を使用する場合は、最初にすべてのレストランを深夜0時から翌日の正午までクロールしてから、各レストランの注文量を次の午後1時から午後2時までクロールすることに焦点を当てます。日。このようにして、注文クロールタスクはわずか6時間で完了し、時間差による注文量の差は減少しました。同時に、店舗は数日おきに取得するため、影響が少ないため、リクエスト数も少なくなり、ウェブサイトでクローラーを見つけにくくなっています。

別の例として、リアルタイムの世論を分析するには、BaiduTiebaをクロールする必要があります。人気のあるTiebaには、最も古い投稿が2010年にさかのぼると仮定すると、何万ページもの投稿がある可能性があります。幅優先探索を採用した場合は、まずこの投稿バーの全投稿のタイトルとURLを取得し、次にこれらのURLに従って各投稿を入力して各フロアの情報を取得します。ただし、リアルタイムの世論であるため、7年前の投稿は現在の分析にとってほとんど重要ではなく、より重要なのは新しい投稿であるため、新しいコンテンツを最初に取得する必要があります。過去のコンテンツと比較して、リアルタイムのコンテンツが最も重要です。したがって、ポストバーのコンテンツをクロールするには、深さ優先探索を使用する必要があります。投稿が表示されたら、すばやくアクセスして各フロアの情報をクロールし、投稿が登った後、次の投稿に登ります。もちろん、これら2つの検索アルゴリズムはどちらか一方ではなく、実際の状況に応じて柔軟に選択する必要があり、多くの場合同時に使用することができます。

おすすめ

転載: blog.csdn.net/weixin_55159605/article/details/124147908