🐍

BeautifulSoup + aiohttpで並列スクレイピング

2020/11/29に公開

背景

  • 不特定多数のページに対してスクレイピングを行いたい。
  • その際ページ数に比例したレイテンシ増加を回避したい。
  • この記事では、非同期I/Oを利用したリクエストを行って上記を実現する。

※非同期I/Oは並列処理とは異なりますが同等の効果が期待できるかと思います。

やること

  • BeautifulSoup(スクレイピング)
  • aiohttp(非同期I/Oを利用したHTTPクライアント)

必要なパッケージ

以下のバージョンで動作確認

requirements.txt
aiohttp==3.7.3
beautifulsoup4==4.9.3

コード

aio-bs4.py
from bs4 import BeautifulSoup
import aiohttp
import asyncio


# リクエストURLのリスト
URLS = [
    'https://example.com',
    'https://example.com?q=a',
    'https://example.com?q=b',
    'https://example.com?q=c',
    'https://example.com?q=d',
]


async def request(url, session):
    async with session.get(url) as response:
        html = await response.text()
        soup = BeautifulSoup(html, "html.parser")
        print(soup.find('title'))


async def main():
    async with aiohttp.ClientSession() as session:
        await asyncio.gather(*[request(url, session) for url in URLS])


if __name__ == '__main__':
    asyncio.run(main())

Discussion