Pythonを使用して、初心者でも理解できる分散型Zhihuクローラーを作成します。

Pythonを使用して、初心者でも理解できる分散型Zhihuクローラーを作成します。

Zhihu のユーザーデータを収集するというアイデアは、かなり以前からありました。このアイデアを実現するには、Web クローラー (Web スパイダー) を作成する必要があります。私は Python を学習していたので、Python でクローラーを作成することも最適な選択であると考えて、Python ベースの Web クローラーを作成しました。

数か月前にクローラーの最初のバージョンを作成しましたが、何らかの理由でそのまま放置していました。最近、私はその考えを再び取り上げました。まず、コードの構造を最適化しました。その後、後輩の注意を受けて、マルチスレッドからマルチプロセスに変更しました。マシン上でクローラー プログラムを実行すると、クロール速度を上げるために何百ものサブプロセスが開始されます。

しかし、マシンのパフォーマンスには限界があるため、後に MongoDB と Redis を使用してマスタースレーブ構造の分散クローリングシステムを構築し、クローリングをさらに高速化しました。

その後、Baidu Cloud、Tencent Cloud、Ucloudなど、いくつかのサーバーベンダーに無料トライアルを申し込みました。自分のラップトップと一緒に、1週間以上断続的にクロールし、300万人のZhihuユーザーからデータを収集しました。ウェブサイトを運営しているクラウドサーバーも途中で故障しましたが、幸い自動バックアップが機能し、データは失われませんでしたが、それはまた別の話です…

早速ですが、シンプルな分散型 Zhihu クローラーの書き方を紹介します。

Zhihuユーザーの個人情報を取得する

学びとコミュニケーションの場としてお勧めしたいです。 Pythonを学びたい友達が集まって一緒に勉強できます。 719+139+688。ピットに入るときは注意してください。 Python に興味がないなら、この楽しみに参加しないでください。 Zhihu ユーザー データをクロールする場合、まずどのページからユーザー データをクロールできるかを知る必要があります。 Zhihuユーザーの個人情報はどこにありますか?もちろん、ユーザーのホームページにあります。ルンジ兄さんを例に挙げてみましょう〜

赤いボックスには、取得したい主要なユーザー情報 (の一部) が含まれています。

一番上には、ターゲット URL があります: https://www.zhihu.com/people/excited-vczh/answers。

この URL の構成を見てみましょう。

  • http://www.zhihu.com + /people + /excited-vczh + /answer

励起された vczh 部分のみが変化することがわかります。これは、Zhihu ユーザーの一意の ID を表します。 Zhihu データ形式では、キー名は urlToken と呼ばれます。

したがって、連結された文字列を使用して、クロールするページの URL を取得できます。

  1. url = '%s/people/%s/answers' %(host,urlToken)

ページ URL は公開されており、上図から、ログインせずにユーザーのホームページにアクセスできることがわかります。つまり、模擬ログインを心配する必要がなく、ユーザーのホームページのソースコードを自由に取得できます。

では、ユーザーのホームページのソース コードからユーザーのデータを取得するにはどうすればよいでしょうか?最初は、ページの対応する部分を 1 つずつ一致させる必要があると考えていましたが、ソース コードを確認すると、Zhihu がユーザー データ セットをソース コードの 1 か所、つまり id="data" の div の data-state 属性の値に配置していることがわかりました (下図を参照)。

上図から、date-state の属性値にユーザー情報が含まれていることがわかります。たとえば、ユーザーの学歴 (educations)、自己紹介 (headline)、参加したライブの数 (participatedLiveCount)、フォローしているお気に入りの数 (followingFavlistsCount)、お気に入りの数 (favoritedCount)、フォローしているユーザーの数 (followerCount)、フォローしているトピックの数 (followingTopicCount)、ユーザーの説明 (description) などの情報を確認できます。観察すると、データは JSON 形式で保存する必要があることもわかります。

ユーザー データが date-state に隠されていることがわかっているので、BeautifulSoup を使用して属性の値を取得し、それを JSON 形式として読み取り、ユーザー データを格納するデータセットの部分を抽出します。コードを参照してください:

  1. # htmls を解析する = BS(html, 'html.parser' )# ユーザーのメインページに隠された json 形式のデータセットを取得する data = s.find( 'div' ,attrs={ 'id' : 'data' })[ 'data-state' ]  
  2. データ = json.loads(データ)  
  3. データ = データ[ 'エンティティ' ][ 'ユーザー' ][urlToken]

このようにして、特定のユーザーの個人情報を取得します。

Zhihuユーザーのフォロワーリストを取得する

先ほど、ユーザーのホームページのソースコードをクロールすることで個人情報を取得できること、また、ユーザーのホームページでは文字列を連結した形で URL を取得できることを説明しました。スプライシングの鍵となるのは、ユーザーの一意の ID (urlToken) をどのように取得するかです。

私が取ったアプローチは、ユーザーのフォロワーリストをスクレイピングすることでした。

各ユーザーには、Lunzi 兄弟のようなフォロワーのリストがあります。

個人情報を取得するのと同じように、ページのソースコードの date-state 属性値で、彼をフォローしているユーザー(一部)を見つけることができます。

ids という名前のキーには、現在のリスト ページ上のすべてのユーザーの urlToken が格納されます。デフォルトでは、リストの各ページには 20 人のユーザーが表示されるため、現在のページのユーザーのフォロワー全員の urlToken を取得するループを記述できます。

  1. # 現在のページの HTML を解析します url = '%s/people/%s/followers?page=%d' %(host,urlToken,page)  
  2. html = c.get_html(url)  
  3. s = BS(html, 'html.parser' )# 現在のページの次のユーザーをすべて取得します data = s.find( 'div' ,attrs={ 'id' : 'data' })[ 'data-state' ]  
  4. データ = json.loads(データ)  
  5. items = data[ 'people' ][ 'followersByUser' ][urlToken][ 'ids' ]アイテム内のアイテムの場合: item!=Noneかつitem!= False の場合 そしてアイテム!= True  そしてitem!= 'zhihu user' .decode( 'utf8' ):
  6. ノード = item.encode( 'utf8' )  
  7. フォロワーリストに追加(ノード)

フォロワー リストのすべてのページを走査する別のループを記述すると、ユーザーのすべてのフォロワーの urlToken を取得できます。

Zhihu 上の各ユーザーの固有 ID を使用すると、この ID を連結することで各ユーザーのホームページ URL を取得し、さらに各ユーザーの個人情報を取得できます。

私は、ユーザーのフォロワー リスト、つまり、このユーザーをフォローしているすべてのユーザー (フォロワー) のリストを取得することを選択しました。実際には、ユーザーのフォローリスト (フォロー中) を取得することもできます。私は、Zhihu の非典型的なユーザー (潜入者) をもっと捕捉したかったので、フォロワー リストを捕捉することにしました。クローリング中、私たちは「主流のユーザーを獲得できなかったらどうしよう」という不安を抱いていました。結局のところ、多くの知乎大Vはフォロワーが多いものの、積極的にフォローしている人は比較的少なく、フォローしている人は大Vである可能性が高いです。しかし事実は、主流のユーザーが基本的に捕らえられていることを証明しています。土台が上がった後は必ず隙間ができてしまうようです。

アンチクローラー機構

頻繁にクロールが行われると、Zhihu によって IP がブロックされます。これは、よく知られているクローラー対策方法の 1 つです。しかし、諺にあるように、「徳が高ければ、悪も高くなる」のです。クローラー対策方法がある以上、クローラー対策方法も必ずあるはずです。まあ、自分で名前を付けただけですが...

話題に戻りましょう。 Zhihu が IP をブロックした場合、どうすればよいでしょうか?簡単です。IP を変更するだけです。このアイデアからプロキシ IP プールが誕生しました。いわゆるプロキシ IP プールは、プロキシ IP の集合です。プロキシ IP を使用すると、アクセス要求が偽装され、サーバーはユーザーが別のマシンからアクセスしていると認識する可能性があります。

したがって、Zhihu のクローラー対策メカニズムに対処するための私の戦略は非常にシンプルです。全力で Zhihu ページをクロールする --> Zhihu が私の IP をブロックする --> プロキシ IP を変更する --> クロールを継続する --> Zhihu がブロックを継続する --> IP を変更し続ける... (手動で目を細める)

プロキシ IP プールを使用する場合は、有料サービスを使用するか、自分で作成するか、既製のホイールを使用するかを選択できます。プロキシ プール サービスを構築するために、Qiye によって作成された qiyeboy/IPProxyPool を使用することを選択しました。デプロイ後、http プロトコルの IP を使用して Zhihu にアクセスすると拒否されるため、https プロトコルのプロキシ IP のみを保存するようにコードを変更しました。

プロキシ プール サービスを設定すると、いつでもコード内でプロキシ IP を取得して使用し、アクセス要求を偽装できます。

(実際、クロール防止方法は数多くあり、プロキシ プールはその 1 つにすぎません)

シンプルな分散アーキテクチャ

マルチスレッド/マルチプロセッシングは、単一のマシンのパフォーマンスのみを最大化します。複数マシンの性能を活用したい場合は分散サポートが必要です。

シンプルな分散クローラーを構築するにはどうすればいいでしょうか?

マスタースレーブ構造を採用しました。つまり、ホストがキャプチャするノードのスケジュールと管理を担当し、複数のスレーブが特定のキャプチャ作業を担当します。

特にこの Zhihu クローラーの場合、ホスト上に MongoDB と Redis の 2 つのデータベースが構築されます。 MongoDB はキャプチャされた Zhihu ユーザー データの保存を担当し、Redis はキャプチャされるノードのセットの維持を担当します。スレーブ マシンでは 2 つの異なるクローラー プログラムを実行できます。1 つはユーザーのフォロワー リストをクロールするクローラー (list_crawler) で、もう 1 つはユーザーの個人情報をクロールするクローラー (info_crawler) です。これらは一緒に使用できますが、お互いに影響を与えません。

ホスト上で管理されているコレクションに焦点を当てます。ホストの Redis データベースには合計 5 つのコレクションが保持されます。

  1. 待機中: キャプチャするノードのセット
  2. info_success: 個人情報が正常に取得されたノードのコレクション
  3. info_failed: 個人情報の取得に失敗したノードのコレクション
  4. list_success: リストに従って成功したノードセットを取得します
  5. list_failed: 監視リストのクロールに失敗したノードセット

ここで付け加えておきますが、キューの代わりにセットが使用される理由は、セットは本質的に一意であるためです。つまり、セットに追加できるノードは、そのセットに一度も出現したことのないノードでなければなりません。ここで 5 つのセットで循環しているノードは、実際には urlToken です。

(実際はセットを3つに減らして失敗したセットを省き、失敗したら元のセットに再投資することもできますが、スピード測定のために5セット構成を維持しました)

彼らの関係は次の通りです。

具体的な例を挙げてみましょう。urlToken が待機コレクションに出現してから、一定時間が経過すると、info_crawler クローラー プログラムによって待機コレクションからランダムに取得され、その後、info_crawler クローラー プログラムで個人情報がクロールされます。クロールが成功すると、個人情報はホストの MongoDB に保存され、urlToken は info_success コレクションに配置されます。クロールが失敗した場合、urlToken は info_failed コレクションに配置されます。次の段階では、一定時間が経過すると、list_crawler クローラーが info_success コレクションから urlToken をランダムに取得し、urlToken で表されるユーザーのフォロワー リストをクロールしようとします。フォロワー リストが正常にクロールされた場合、クロールされたすべてのフォロワーは待機コレクションに配置され、urlToken は list_success コレクションに配置されます。クロールが失敗した場合、urlToken は list_failed コレクションに配置されます。

このようにして、ホストによって維持されるデータベースは、スレーブの info_crawler および list_crawler クローラー プログラムと連携して循環することができます。info_crawler は、待機セットからノードを継続的に取得し、個人情報を取得してデータベースに保存します。 list_crawler は待機セットを継続的に補充します。

ホストとスレーブの関係は次のとおりです。

ホストはインターネット/LAN にアクセス可能な「サーバー」であり、スレーブは PC/ラップトップ/Mac/サーバーになります。このアーキテクチャは、インターネットまたはイントラネット上に展開できます。

<<:  マルチクラウドデータ管理環境におけるすべての要素の検討

>>:  WOT Shi Yang: IoT時代のインテリジェントエッジコンピューティング

推薦する

httpzoom-3.48 ポンド/4g メモリ/4g スワップ/50g ハードディスク/2T トラフィック/英国

httpzoom は 2009 年に VPS の運営を開始しました。割引や宣伝も比較的少なかったので...

desivps: サンノゼ VPS、年間 18.99 ドル、1G メモリ/1 コア/25g SSD/1Gbps 帯域幅 + 無制限トラフィック、6 回の無料 IP 変更

desivps からプロモーション メールが届きました。基本的には、desivps が dedipa...

中小規模のウェブマスターの皆様、地方の小規模ウェブサイトで年間150万元を稼ぐ4つの方法をご紹介します。

Discuz! 愛好家が4月15日に報告(文/ウェブマスター Ajian)今日、あるウェブマスターが...

サーバーレス クラウド セキュリティ: サーバーレス コンピューティングを保護する方法

サーバーレス コンピューティングは、クラウド コンピューティングの開発トレンドの 1 つであり、最も...

パブリッククラウドのコスト管理に役立つ28の効果的な対策

クラウドが新たな標準となり、企業がデジタル変革計画を加速するにつれて、IT 環境は完全に変化しました...

ftpit: プレミアム マーチャント、月額 1.49 ドル、KVM/256M メモリ/1 コア/10g ハード ディスク/512G トラフィック

ftpit から最新のプロモーション メールを受け取りました。このメールには、西海岸のフリーモントと...

重慶ショッピングマッドネスウェディングコラムの分析例から、フォーラムSEOの作成方法を学ぶ

私は重慶に出張していたので、当然地元のウェブサイトに注目していました。「重慶ショッピングホリック」と...

webhostingbuzz - ウェブホスティング + リセラーが 60% オフ

webhostingbuzzはバレンタインデーのホストプロモーション情報をリリースし、仮想ホストと再...

SEO なしではウェブサイトは存続できないのでしょうか?

SEO2.0 が登場する前は、少しの最適化で、検索エンジンにおけるウェブサイトのパフォーマンスをすぐ...

Fu Sheng: 製品デザインの方法はシンプルさと美しさです。私たちは少人数向けのデザインにこだわっています。

編集者注: この記事は、8 月 18 日に開催された HDCon 人間中心設計カンファレンスで Ki...

budgetvm-E3-1270v3/32g メモリ/2T ハードディスク/5IP/30T トラフィック/月額 149 ドル

budgetvm は、低価格の VPS やサーバーレンタルの分野ではユニークな会社です。驚くほどの低...

ハイブリッドクラウドデータバックアップ

バックアップにハイブリッド クラウドを使用すると、組織はオンプレミス展開の制御を損なうことなく、クラ...

業界ポータルサイト向け SEO 最適化ソリューション

SEO といえば、外部リンクの追加、キーワードの位置、URL ルールなどを思い浮かべる人が多いでしょ...

ASO 最適化ルール | 低予算で最適化する方法を教えます!

製品が作られると、正式発売はゼロから1へのプロセスであり、1から100への道はトラフィックの獲得と商...

世界中の40の1桁ドメイン名の現状:約3分の1がパークページ

「短い」というのは、良いドメイン名を判断する基準の一つです。1桁のドメイン名には明らかな利点がありま...