PythonとChromeを使用したWebクローラー

親愛なる友人、こんにちは。



最近、ソファに座って、ウェブサイトから何かをダウンロードできる自分のクモをどうやって作りたいか考えました。 ただし、単純なダウンロードではなく、実際のかわいい種類のブラウザ(つまり、実行されるJavaScript)のようにダウンロードされている必要があります。



Selenium、PhantomJS、Splashなどの興味深いものが頭に浮かびました。 これらすべては私にとってはちょっとした引き込みでした。 私が特定した理由は次のとおりです。





実際には、ポイントに。 ヘッドレスChromeが最近リリースされました。 これは、クロームを既にクローラーとして使用していることを意味します(ただし、これは不正確です)。 ただし、クローラーとして使用するための通常のユーティリティは見つかりませんでした。 サードパーティのクライアントのリストからchrome-remote-interfaceのみを見つけました(残りは非常に退屈で一見完全に理解できませんでした)。



ドキュメントと完成したプロジェクトを実行し、誰も実際にPythonでクライアントを実装していないことを確認して、私は自分のクライアントを作成することにしました。



Chromeリモートデバッグのプロトコルは非常に簡単です。 開始するには、次のパラメーターを使用してChromeを実行する必要があります。



chrome --incognito --remote-debugging-port=9222 --headless
      
      





画像



これで、 http://127.0.0.1:9222 / json /でAPIを使用できます。このAPIには、タブの管理に使用されるlistnewactivateversionなどのメソッドがあります。



また、 http://127.0.0.1:9222/に移動するだけで、標準のWebデバッガーを完全に模倣する素晴らしいWebデバッガーに切り替えることができます。 Chromeのapishメソッドの動作を監視することは非常に便利です(右側のデバッグウィンドウはウィンドウ内でエミュレートされ、ブラウザーウィンドウはキャンバスに描画されます)。



画像

実際、 リストタブに移動することで、タブと通信できるWebソケットのアドレスを見つけることができます。



次に、Webソケットを介して目的のタブに接続し、通信します。 できること:





数日かけて自分のために機能的に書いた後、私はそのようなライブラリを手に入れました。



中身は何ですか:





画像

これはプログラムがどのように見えるかで、ページをロードし、リクエストに対する各レスポンスの長さを示します:



 import asyncio import chrome_remote_interface if __name__ == '__main__': class callbacks: async def start(tabs): await tabs.add() async def tab_start(tabs, tab): await tab.Page.enable() await tab.Network.enable() await tab.Page.navigate(url='http://github.com') async def network__loading_finished(tabs, tab, requestId, **kwargs): try: body = tabs.helpers.unpack_response_body(await tab.Network.get_response_body(requestId=requestId)) print('body length:', len(body)) except tabs.FailReponse as e: print('fail:', e) async def page__frame_stopped_loading(tabs, tab, **kwargs): print('finish') tabs.terminate() async def any(tabs, tab, callback_name, parameters): pass # print('Unknown event fired', callback_name) asyncio.get_event_loop().run_until_complete(chrome_remote_interface.Tabs.run('localhost', 9222, callbacks))
      
      





ここでは、コールバックシステムを使用します。 最も興味深い: startany





私のコードは私には十分にエレガントであるように見え、プロトコルは少し湿っていますが、さらに使用します。 誰かが議論したい場合は、 Githubまたはメールでこちらに書いてください。



しかし、一つだけありましたが、そのために私はまだ泣いています。 リモートAPIを使用して、要求と応答をインターセプトおよび変更することはできません。 私がそれを理解しているように-これはmojoを介して可能であり、これによりchromeをライブラリとして使用できます。



しかし、不安定なクロムのコンパイルとPythonレイヤーの欠如は、私にとって大きな悲しみになると思いました(現在、開発プロセスにはC ++とJavaScriptがあります)。



記事がお役に立てば幸いです。 ありがとう



画像







All Articles