PHPでのコンテンツアグリゲーターの電報チャネルの解析

こんにちは、Habr!



数年前、Webサーフィンを簡単にするためにコンテンツアグリゲーターの開発を始めました。 最初は、rss、vk、facebookのみを解析しましたが、昨年、プロジェクトの完全なリファクタリングを行うことにしました:クライアントでの解析を拒否し、通常のバックエンドを作成し、データベースを使用してデータを保存し、サポートされるリソースのリストを拡張します。



rss、fb、vk、twitter、instagram、youtubeの標準セットに加えて、電報からの任意のオープンチャネルのサポートを追加しました。



画像






猫の下で登録とSMSなしで電報のチャネルを解析する方法についての手順を追って説明します。





[2019-03-12更新]

電報チャネルの解析に関する新しい投稿: habr.com/en/post/354000 より良いコード、オープンソースのマイクロサービス、テスト用の新しい公開サーバー。



最初は、人気のあるBotApiを介してチャネルを解析できると想定していました。BotApiには、ネットワーク上で多くの指示がありました。 しかし、ボットが何らかのチャネルを読み取れるようにするには、ボットをこのチャネルに追加する必要があることが判明しました。 サードパーティのチャネルの場合、このオプションは使用できません。 メインの電報APIでマニュアルを読むことに切り替えました。



ドキュメントを30分間勉強した後、私は必死でした。 テレグラムからのすべてのデータは暗号化されます。サーバーから何かを取得するには、暗号学の修士号を取得する必要があります。そして、httpリクエストの代わりに、ソケットを使用します。 一般的に純粋なハードコアで、ネット上のわかりやすい例はありません...それはほとんど大失敗でした。



最後の希望は、何らかの既成のソリューションを見つけることでした。 そして最後に、運が私に微笑んだ。 電報のWebサイトで、非公式のオープンソースphpクライアントへのリンクに出会いました。 はい、はい! あなたはPHPで電報を使用することができ、呼び出しのサポートもあります! この奇跡はmadelineProtoと呼ばれます。 暗号マジックを使用してサーバーに接続し、必要なデータを通常の人間の連想配列の形式で返すことができます。



PHPクライアントの構成を開始しました。



1.顧客を登録します。



残念ながら、投稿の冒頭で私はあなたをだましました、そして、我々はまだ電報で登録とSMS認可を必要とします...



画像






すでに電報にアカウントを持っている場合は、アプリケーション/クライアントを登録し、電報サーバーにアクセスするためのキーを取得します。



これは、ソーシャルの手順に似た標準的な手順です。 APIにアクセスするためのネットワーク。 キーを作成する手順。



クライアントを登録した後、 my.telegram.org / appsページから「App api_id」と「App api_hash」のみが必要です。



2. madelineProtoをインストールします。



動作するにはphp7が必要ですが、Readmeではphp5.6で実行する方法があると述べています。



Mampパッケージのphp7を使用してMacOで実行しても問題はなく、1か月あたり150ルーブルのシンプルなホスティングもありました。



プロセスはトリッキーではありません。リリースをダウンロードし、composerを使用して依存関係をインストールすれば、構成を続行できます。



サイズを小さくするために、余分な依存関係を削除し、danog、paragonie、phpseclibのみを残しました。 これはクライアントの仕事には影響しませんでした。



3. madelineProtoを構成し、最初に実行します。



使用および構成のすべての例はクライアントリポジトリに記載されていますが、コードにはコメントを付けます。



この段階で、新しい接続を認証し、認証コードを入力する必要があります。認証コードは、以前に認証された電報クライアントに届きます。 コンソールからコードを実行することをお勧めします(ただし、Webモードもあります)。 他の人のためにクライアントを設定している場合、電信経由で認証コードを送信することはできません。そうしないとキャンセルされます。 ただし、スクリーンショットとして送信するか、テキストで書き込むことができます。



要求できる認証の数は制限されています。 何かが機能しない場合は、コードを連続して何度も実行しないでください。そうしないと、Telegramは1日以上の確認の送信をブロックします。



残念ながら、私は自分の肌でこの機能について学びました。 通常の技術。 ちなみに、電報もサポートされていないため、ブロックする場合は待つ必要があります:)



//   ,  -  . C        ReadMe   github. $settings = [ 'app_info' => [ //         https://my.telegram.org 'api_id' => XXXXX, 'api_hash' => XXXXXXXXXX, ], 'logger' => [ //     'logger' => 3, //    echo 'logger_level' => 4, //    . ], //    socks5  //   ,     . 'connection_settings' => [ 'all' => [ 'proxy' => '\SocksProxy', 'proxy_extra' => [ 'address' => 'xxx.xxx.xxx.xxx', 'port' => 1234, 'username' => '',//     'password' => '',//     ], ], ], 'serialization' => [ 'serialization_interval' => 300, //     . //      ,     'cleanup_before_serialization' => true, ], ]; $MadelineProto = new \danog\MadelineProto\API('session.madeline', $settings); $MadelineProto->start();
      
      







ファイル「session.madeline」がプロジェクトのルートに作成され、バイナリ形式でセッションのデータが保存されます。 再起動すると、再度ログインする必要はありません。 セッションの再開は非常に高速です。 外部サーバーでクライアントを初期化するには、約800ミリ秒かかります。



設定を更新するには、アレイを更新してスクリプトを再起動するだけです。 セッションファイルを削除する必要はありません。



4.任意のオープンテレグラムチャネルから投稿を取得します。





 $data = array( 'peer' => '@'.$val['url'], //_,    @,  @breakingmash,   ,  limit,    0 'offset_id' => $val['offset_id']?:0, 'offset_date' => $val['offset_date']?:0, 'add_offset' => $val['add_offset']?:0, 'limit' => $val['limit']?:10, // ,    'max_id' => $val['max_id']?:0, // id  'min_id' => $val['min_id']?:0, // id  -   ,  0   . 'hash' => 0 ); $response = $MadelineProto->messages->getHistory($data);
      
      





一度に多くのチャネルを更新するため、各チャネルで2秒を費やすのではなく、同じセッションを使用するのが理にかなっています。



実行後、必要な投稿/投稿の数をチャネルで分割した配列を取得します。 メディア投資に関するデータも送信されます。



次に、写真/ビデオがある場合は投稿のテキストを保存し、メディアファイルのプレビューと署名を取得し、投稿を表示するためのリンクを作成します。



4.メディアの添付ファイルを取得します。



幸いなことに、最近、電報は投稿のhtmlプレビューを導入したため、クライアントから受信したバイナリデータをサーバーに保存することはできず、電報サーバーに保存されている写真やビデオへのリンクを取得するだけです。



チャンネル名と投稿ID を使用して 、フォーマットリンクを形成します: t.me/CHANNEL_NAME/POST_ID?embed=1 、たとえばt.me/breakingmash/4193?embed=1



それでは、すべてが簡単です。



 private function telegram_media_parse($posts_data, $source){ include_once(ROOT_DIR.'/libs/phpQuery.php'); //  html       phpQuery foreach ($posts_data as &$post_data) { if (!empty($post_data['media'])){ $file_contents = self::loader($post_data['post_url'],'site');// curl  html   . $document = phpQuery::newDocumentHTML($file_contents); // dom-  html  $post_data['post_image'] = preg_replace('/[\s\S]*background-image:[ ]*url\(["\']*([\s\S]*[^"\'])["\']*\)[\s\S]*/u','$1',$document->find($source['rules']['post_img_path'])->eq(0)->attr('style')); //    background-image . $post_data['post_description'] = $document->find($source['rules']['post_text_path'])->eq(0)->text(); // caption . } unset($post_data['media']); } unset($post_data); return $posts_data; }
      
      





この解析は完了し、投稿をデータベースに保存したり、ページに表示したりできます。



私の最初の投稿が誰かに役立つことを願っています。 アグリゲーターへのリンクを残しません。これが許可されているかどうかわかりません。



All Articles