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時代のインテリジェントエッジコンピューティング

推薦する

Vultr VPS レビュー (日本 VPS、512m メモリ)

私はVultrの日本のデータセンターでVPSを購入し、Vultrの簡単なレビューを書きました。もっと...

クラウド コンピューティングはなぜ企業の間でこれほど普及したのでしょうか?

クラウド コンピューティングとは、並列コンピューティング、分散コンピューティング、グリッド コンピュ...

医療業界は「微博をコントロールする」から「微博をコントロールする」まで、ほんの数ステップで済む。

バスの中で携帯電話を手に持ち、自分の生活をライブストリーミングしている男女をよく見かけます。彼らは典...

新しいサイトのスナップショットとソリューションの組み込みに影響する要因の解釈

新しいウェブサイトがオンラインになるたびに、ウェブマスターはこのウェブサイトに非常に失望しています。...

初心者でも毎日高品質なソフト記事を書けるようになる方法

ソフトコンテンツマーケティングは非常に効果的なマーケティング手法ですが、非常に難しいものでもあります...

Alibaba Cloudデータセンターのアップグレードにより、きめ細かなシナリオが深まり、新しい小売業のデジタル化が加速

9月18日、2020年雲奇カンファレンスにおいて、アリババクラウドのデータミドルウェア製品が全面的に...

知っていましたか?ハイブリッドクラウドに向けた最善の次のステップ

ハイブリッド クラウド インフラストラクチャを活用することを決定した企業には、選択できるオプションが...

RFCHOST - VPS 新年 20% オフ、高品質 GIA CN2/ロシア ハバロフスク、Alipay

RFCHOST 新年プロモーション、ロサンゼルス GIA CN2 ライン、ロシア ハバロフスク、これ...

AirbnbがQyer.comと提携。この優れたモデルは中国市場で導入できるだろうか?

[劉楊/チタンメディア編集長] 5月29日、海外旅行に特化した地域コミュニティサイトQyer.com...

Baidu の検索結果にホームページ URL のみが表示されることの影響

今日の午後、ある単語を検索したところ、Baidu が検索結果を調整して、ウェブサイトのホームページの...

新しいサイトの急速なランキングに影響を与える最大の要因は何ですか?

新しいウェブサイトが最短時間でランキングのメリットを最大化する方法こそが、すべての SEO 担当者が...

百度とキングソフトは問題の是正に向けて新たな一歩を踏み出したが、批判を浴びている。

百度が数か月以内に行った調整は、検索結果の品質向上に向けた同社の決意を示している。360 Searc...

100億ドル規模の自動車旅行市場をつかむ:モバイルインターネットの次の金鉱

代表的な車内旅行アプリのまとめ一方では旅行需要が旺盛で道路が混雑しているが、もう一方には非効率で空い...

電子メールを活用して e コマース サイトの飛躍を促進 (パート 2)

前回の記事「電子メールに翼を与えて、電子商取引サイトの飛躍を助けましょう(パート 1)」では、電子メ...

モバイル 3G マーケティングでは量が重要ですか?多様性、包摂性、アウトプットが鍵

企業にとって、インターネット マーケティングは馴染みのないものではありません。今日のインターネットの...