PuppeteerとPythonの使い分け
Webスクレイピングには大きく2つのアプローチがあります。
| アプローチ | ツール | 向いているケース |
|---|---|---|
| HTTPリクエストベース | Python requests + BeautifulSoup | 静的HTML・シンプルなサイト |
| ヘッドレスブラウザ | Puppeteer | JavaScript描画コンテンツ |
今回はPythonでの静的サイトスクレイピングを解説します。
環境構築
pip install requests beautifulsoup4 pandas lxml
基本的な実装
import requests
from bs4 import BeautifulSoup
import time
import random
def scrape_page(url: str) -> BeautifulSoup:
"""単一ページを取得してBeautifulSoupオブジェクトを返す"""
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36',
'Accept-Language': 'ja-JP,ja;q=0.9',
}
response = requests.get(url, headers=headers, timeout=15)
response.encoding = response.apparent_encoding
return BeautifulSoup(response.text, 'lxml')
def extract_products(soup: BeautifulSoup) -> list[dict]:
"""商品情報を抽出する"""
products = []
for item in soup.select('.product-item'):
products.append({
'name': item.select_one('.product-name').get_text(strip=True),
'price': item.select_one('.price').get_text(strip=True),
'url': item.select_one('a')['href'],
})
return products
# 複数ページを収集
all_products = []
for page in range(1, 11): # 10ページ分
url = f'https://example.com/products?page={page}'
soup = scrape_page(url)
all_products.extend(extract_products(soup))
# 礼儀正しいスクレイピング:1〜3秒待機
time.sleep(random.uniform(1, 3))
pandasでデータを整形・保存
import pandas as pd
df = pd.DataFrame(all_products)
df['price_num'] = df['price'].str.replace('[¥,円]', '', regex=True).astype(int)
df = df.sort_values('price_num')
# CSV保存
df.to_csv('products.csv', index=False, encoding='utf-8-sig')
# 集計
print(f"平均価格: ¥{df['price_num'].mean():,.0f}")
print(f"最安値: ¥{df['price_num'].min():,}")
まとめ
Pythonのrequests + BeautifulSoupは学習コストが低く、シンプルなスクレイピングなら数十行で書けます。まずはこちらで試して、JavaScriptが必要な場面でPuppeteerに切り替えるのが効率的です。