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があります)。

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

画像

Source: https://habr.com/ru/post/J328800/


All Articles