
Playwrightで非同期処理を行う際に必ず登場するのが、asyncio.run()
という関数です。
この記事では、asyncio.run()
の基本的な意味や使い方から、なぜ必要なのかの理由まで、初心者にもわかりやすく丁寧に解説します。
asyncio.run() とは?
asyncio.run()
は、Pythonの asyncio
モジュールに含まれる 非同期関数を実行するための関数 です。
非同期処理とは、一つの処理を待っている間に他の処理を並行して実行する仕組みで、効率的なプログラム実行を可能にします。
この関数を使うと、async def
で定義された非同期関数を、通常のPythonプログラムから実行できるようになります。
これにより、Playwrightの高速なブラウザ操作を活用した効率的なWebスクレイピングが実現できます。
具体例①:基本的な使い方
まずは、asyncio.run()
を使った基本的なPlaywrightコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: browser = await p.chromium.launch() page = await browser.new_page() await page.goto("https://example.com") title = await page.title() print(title) await browser.close() asyncio.run(main()) |
このコードでは、main()
関数を async def
で定義し、asyncio.run(main())
で実行しています。
例えば、上記のコードを実行すれば、実行結果としてhttps://example.comのページタイトル(例えば、 "Example Domain"
) のようなタイトルが表示されます。
具体例②:asyncio.run()を使わない場合のエラー
asyncio.run()
を使わずに非同期関数を直接実行しようとするとエラーになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: browser = await p.chromium.launch() page = await browser.new_page() await page.goto("https://example.com") title = await page.title() print(title) await browser.close() # これはエラーになる main() |
この方法だと、RuntimeWarning: coroutine 'main' was never awaited
というエラーが発生し、期待した処理が実行されません。
asyncio.run()がなぜ必要なのか
asyncio.run()がなぜ必要なのか?
それは非同期関数を実行するためには、特別な仕組みが必要だからです。
通常の関数
→ 上から順に実行され、一つの処理が終わってから次に進む
非同期関数(async def)
→ 複数の処理を並行実行するため、専用の「イベントループ」が必要
イベントループの役割
- 非同期処理の実行順序を管理
- 待機中の処理を一時的に停止し、他の処理を実行
- 完了した処理の結果を適切に返す
asyncio.run()
は、このイベントループを自動的に作成・管理してくれる便利な関数なのです。
複数の非同期処理を並行実行する場合
asyncio.run()
は、複数のタスクを並行実行する際にもその真価を発揮します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import asyncio from playwright.async_api import async_playwright async def scrape_page(url): async with async_playwright() as p: browser = await p.chromium.launch() page = await browser.new_page() await page.goto(url) title = await page.title() await browser.close() return title async def main(): urls = [ "https://example.com", "https://google.com", "https://github.com" ] # 複数のタスクを並行実行 tasks = [scrape_page(url) for url in urls] results = await asyncio.gather(*tasks) for result in results: print(result) asyncio.run(main()) |
この方法を使えば、3つのWebサイトを同時並行でスクレイピングでき、順次処理より大幅に高速化できます。
特にAPIキーの取得やデータベースへの保存など、外部リソースとの連携が多い場合に効果的です。
活用シーン
asyncio.run()
は、次のような場面で役立ちます。
- 大量のWebページスクレイピング
複数のURLを並行処理することで、処理時間を大幅に短縮できます。 - API連携との組み合わせ
スクレイピング結果をAPIに送信する処理も非同期で並行実行できます。 - 定期的なデータ収集
複数のサイトから定期的にデータを収集するバッチ処理に最適です。
これらの使い方によって、処理効率が向上し、リソースの有効活用が可能になります。
注意点
便利な asyncio.run()
ですが、使う際には以下の点に注意しましょう。
asyncio.run()
は一つのプログラム中で一度だけ呼び出すのが基本です。複数回呼び出すとエラーになる場合があります。
1 2 3 4 5 6 7 8 9 10 11 |
# NG: 複数回の呼び出し asyncio.run(task1()) asyncio.run(task2()) # エラーの可能性 # OK: 一度の呼び出しで複数タスクを実行 async def main(): await task1() await task2() asyncio.run(main()) |
- 非同期処理内では、必ず
await
キーワードを使って非同期関数を呼び出す必要があります。 - 並行処理数が多すぎると、システムリソースを圧迫する可能性があるため、適切な制限を設けることが大切です。
まとめ
今回は asyncio.run()
の意味と必要性を紹介しました。
asyncio.run()
は 非同期関数を実行するための重要な関数- イベントループの自動管理・簡潔な記述・安全な実行が特徴
- 直接実行では エラーになるため、必須の仕組み
- 並行処理による高速化など、幅広いシーンで活躍
Playwrightを効率よく活用するうえで、asyncio.run()
の理解と正しい使い方は欠かせません。
Pythonで非同期ブラウザ操作を行うなら、まず覚えておきたい基本関数のひとつです。