asyncioとは何ですか?
Scrapeless Scraping Browserは、Pythonアプリケーションが非同期ウェブコレクションワークフロー内で調整できるクラウドブラウザ実行を提供します。
asyncioは、asyncとawaitで非同時性のコードを書くためのPythonの標準ライブラリです。イベントループを通じてコルーチン、タスク、および非同期I/Oを調整します。スクレイピングアプリケーションでは、asyncioは、プログラムが各操作の完了時期を追跡しながら、独立したネットワーク待機を重ねることができます。
asyncioはHTTPクライアントでもHTMLパーサーでもありません。ドキュメントをリクエストするには非同期ネットワーキングライブラリを使用し、その内容を抽出するにはパーサーを使用します。asyncioは、これらの操作の間の調整を提供します。この境界を理解することが、その有用性と、明らかに非同期なプログラムがそれでも逐次的に実行される一般的な理由の説明に役立ちます。
asyncioはどのような問題を解決しますか?
asyncioは、操作が適切なI/Oを待っている間に、プログラムが他の作業を進めるのを助けます。ページリクエストは、接続や応答バイトを待つのに時間を費やすことがあります。アプリケーションが別の独立したリクエストを開始する前にその応答を必要としない場合、これらの待機期間は重なり合うことができます。
その Python非同期I/Oモデル は、ネットワーク操作、タスク、サブプロセス、および同期のための高レベルの機能を提供します。ライブラリはこれらの機能を基にして、イベントループと協調する操作を提供します。アプリケーションは、どの作業が独立しているか、どれだけ受け入れるかを決定する責任があります。
役立つ例は、無関係な公開ドキュメントページのセットです。プログラムは、別のリクエストが進行中の間に1ページを待つことができます。依存するワークフローは異なる動作をします:次のアドレスが現在の応答の中にしか存在しない場合、その特定の依存関係は逐次的のままです。非同期シンタックスは、実際のデータ依存関係を取り除くことはできません。
コルーチン、タスク、およびイベントループ
コルーチンは非同期操作を説明し、タスクは実行のためにコルーチンをスケジュールし、イベントループは準備された作業を調整します。コルーチン関数を呼び出すと、自動的にその本体を完了するのではなく、コルーチンオブジェクトが作成されます。呼び出し元はそれを待機するか、タスクとして実行するように手配しなければなりません。
その Pythonコルーチンとタスクのライフサイクル は、スケジューリング、待機、および完了がどのように相互作用するかを説明します。1つのイベントループスレッド内で、タスクは一時停止または終了するまで実行され、他の準備された作業がその後進行することができます。これは協力的スケジューリングであり、イールドせずにループを占有するコードは、無関係なタスクを遅延させる可能性があります。
Awaitは、現在のコルーチンがawait可能な結果に依存していることを意味します。操作が待機しなければならない場合、制御はイベントループに戻ることができます。それは「バックグラウンドスレッドを開始する」という意味ではなく、毎回一時停止が発生することを保証するものでもありません。すでに完了した操作は直ちに続行できます。
通常のスクリプトの境界で、asyncio.runは非同期エントリポイントを管理します。すでにイベントループを持っているホスト、例えば一部のインタラクティブな環境やサービスの内部では、そのホストがサポートする非同期統合を使用し、ネストされたループを開始しようとしないでください。ループを作成するコンポーネントもそのライフサイクルを所有する必要があります。
同時実行はCPUの並列性とは異なる
asyncioは重なり合う操作を調整します。自動的にCPU集約型のPython関数を複数のコアで実行するわけではありません。長い計算や同期的なパーサー呼び出しは、依然としてイベントループスレッドを占有する可能性があります。ネットワーク部分は非同期である場合もありますが、ローカル処理はボトルネックのままです。
Pythonの イベントループ作業に関するガイダンス は、ブロッキング操作が別の処理を必要とする理由を説明します。依存関係がブロッキングI/Oインターフェイスしか公開しない場合、スレッドベースのブリッジが適切かもしれません。CPU集約型の処理には、ランタイム、ライブラリ、およびデータ移動のコストに基づいて異なる実行戦略が必要な場合があります。
実行モデルを変更する前に測定してください。リクエストがソースで待っている時間がほとんどの場合、重なり合う待機が役立つかもしれません。各応答がループを占有する大きな変換を引き起こす場合、より多くのスケジュールされたダウンロードはメモリ圧力を増加させるだけかもしれません。制御された処理段階を持つ小さなアクティブセットは、より予測可能な完了を生むことができます。
| ワークロード | asyncioの役割 | 追加の決定 |
|---|---|---|
| 独立したHTTPリクエスト | 重なり合う待機を調整する | 非同期クライアントとソースの制限を選択します。 |
| 逐次ページネーション依存 | 必要な各応答を待つ | 依存関係の周りにある独立した作業を特定します。 |
| 大きなローカル変換 | 周囲のワークフローを調整する | CPU作業の実行場所を選択します。 |
| 遅い出力ストレージ | 互換性のあるライターを待つ | ストレージの前に受け入れられたバックログを制限する。 |
なぜAwaitがあるループがそれでも逐次的である可能性があるのか
次の操作を作成する前に1つの操作を待機するループは、これらの操作を逐次的に処理します。これは、順序またはデータ依存関係がそれを必要とする場合に、正しい設計である可能性があります。独立した作業には、同時性が必要で、すべての結果を待つ前にいくつかの操作をスケジュールする必要があります。
タスクグループは、関連するタスクのスコープを提供し、グループが終了する際にそれらを待ちます。また、障害が兄弟タスクに与える影響も定義します。結果を収集することは別の調整パターンですが、その失敗の動作はタスクグループと同一ではありません。所有権と完了のセマンティクスに基づいて原始的なものを選択し、単に短い例だけでなく。
成果が重要な作業への参照を保持します。所有者なしで起動された操作は、その結果をプログラムの残りの部分が考慮せずに失敗する可能性があります。コレクションタスクは、入力のアイデンティティ、完了状態、および例外が観察される場所を持っているべきです。これらの特性は、作業が小さいか大きいアクティブセットを持っているかに関わらず重要です。
キューとセマフォは異なるリソースを制御します
バウンスキューは、消費者を待っている認められた作業を制限しますが、セマフォは保護された操作への同時アクセスを制限します。これらの制御は互いに補完し合いますが、互換性はありません。ネットワーク呼び出しの周りのセマフォは、大量の事前作成されたタスクがメモリで待機することになります。
その asyncioキューモデル は、設定されたキューが満杯のときにプロデューサーを待機させることができます。これはバックプレッシャーを引き起こします:消費者が追いつけないと、製造が遅くなります。したがって、ワーカーに基づくコレクタは、アクティブな操作と開始を待っている作業の両方を制限できます。
リソースが存在する場所に制限を適用します。ソース特有のリクエスト制限は、そのソースとの関係を保護します。ブラウザセッションの制限は、ブラウザの容量を保護します。出力キューの制限は、ストレージが収集よりも遅いときにメモリを保護します。アプリケーション全体を囲む1つのセマフォは、これらの制約すべてを説明するにはしばしば曖昧すぎます。
また、アクティブな同時性とリクエスト率を区別します。非常に高速なリクエストの少数でも頻繁なトラフィックを生むことがあります。ソースに適したアクティブ作業の制限とペーシングの両方を選択します。すべてのコレクションの普遍的な設定として任意のワーカー数を提示するのは避けてください。
キャンセルとシャットダウンには所有権が必要
キャンセルは非同期操作に停止を求め、シャットダウンはその操作が所有するリソースを考慮しなければなりません。キャンセルされたタスクは、応答を解放したり、ブラウザページを閉じたり、未完了の入力を記録する必要があるかもしれません。クリーンアップはプロセスの終了が処理するという期待的な仮定ではなく、その操作のライフサイクルに属します。
コンテキスト管理されたリソースと明示的な完了会計を使用します。タスクがネットワーク応答を所有している場合、そのクリーンアップは処理が停止してもその応答を解放する必要があります。出力レコードを所有している場合、そのレコードがコミットされたか未完了のままであるかを判断します。キャンセルは未完了の項目を成功した空の結果に静かに変えるべきではありません。
明確なシャットダウンシーケンスは新しい入力の受け入れを停止し、アクティブ作業ポリシーを解決し、依存するクライアントが終了した後に共有クライアントを閉じます。正確な方針はアプリケーションによって異なります:いくつかのジョブは認められたアイテムを終了させるべきであり、他のジョブはすぐに停止すべきです。いずれにせよ、実行報告書は未処理の内容を説明する必要があります。
イラスト付きの非同期コレクションパイプライン
非同期コレクションパイプラインは、バックログごとに制約を維持しながら、発見、獲得、検証、格納を調整できます。承認された公開文書のURLのリストを想像してください。プロデューサーがそれらのアドレスをワーカーに供給し、ワーカーが文書を取得し、受け入れられたレコードを出力ステージに渡します。
獲得方法は調整モデルを変更せずに異なる場合があります。非同期HTTPクライアントは、既にデータが含まれる応答のページに適しています。 Scrapeless Scraping Browser は動的ページのためのブラウザ実行を提供します。それぞれの操作は、依然として定義された入力、期待される結果、およびリソーススコープを必要とします。
その Scraping Browserの紹介 はブラウザサービスを説明しますが、Pythonにおける 動的ウェブサイトのコレクション についての議論は関連するコンテキストを提供します。レンダリングはタスク制限やフィールド検証の必要性を排除するものではなく、文書を生成する取得ステージを変更します。
完了したレコード、却下された文書、および未完了の入力を別々に追跡します。使用する Scrapeless pricing は設計の一部である場合、ブラウザリソースを評価します。より多くのタスクをスケジューリングすることは、有用な出力が良くなったことによって正当化されるべきです。アクティブな操作として表示される数によってではなく。
結論
asyncioはPythonに対して同時I/Oを調整するための明示的なモデルを提供します。独立した待機を特定することから始め、タスク、キュー、リソースに明確な所有者を割り当てます。結果として得られるプログラムは、何がアクティブであり、何が待機しており、何が完了したのかを説明する必要があります。たとえ操作が失敗したり、ジョブが早期に停止しても。
動的ページコレクションの調整
ページ実行レイヤーにはScrapeless Scraping Browserを使用し、タスクの所有権、キューの制限、および出力の検証をPythonアプリケーションに保持します。
今すぐサインアップして、 5ドルの無料クレジットを受け取ってください — クレジットカードは不要.
$5のクレジットを請求する →FAQ
Q: asyncioはPythonの一部ですか?
asyncioはPythonの標準ライブラリの一部です。それは完全なHTTPスクレイピングスタックではなく、非同期調整を提供します。ソースがデータをどのように公開するかによっては、非同期HTTPクライアント、HTMLパーサー、またはブラウザ自動化ライブラリが依然として必要になる場合があります。
Q: awaitは新しいスレッドを開始しますか?
awaitは新しいスレッドを開始しません。コルーチンモデル内でawait可能なものを待ち、操作が保留中の間にイベントループが他の準備が整った作業を実行できるようにします。スレッド実行は適切なAPIまたはライブラリを通じて行う別の選択です。
Q: なぜ私の非同期スクレイパーはまだ1回のリクエストを同時に実行しますか?
非同期スクレイパーは、次の独立したリクエストをスケジュールする前に各リクエストをawaitする場合、逐次的です。操作が重複できる場合にのみ明示的なタスク調整を導入し、認められた作業に制限を設けます。現在の応答で見つかった次のページアドレスなどの依存関係は逐次的に残ります。
Q: セマフォはすべてのメモリ増加を防ぎますか?
セマフォはそれが保護する操作へのアクセスを制限しますが、アプリケーションが作成するタスクや結果の数を自動的に制限するものではありません。入力リストや応答ボリュームが利用可能なメモリを超える場合には、バウンスキューや制御された出力バッファリングも使用してください。