第32回「スクレイピング(4)」複数ページを自動で巡回する(ページネーション)

こんにちは、小澤です。

前回は、BeautifulSoupを使ったスクレイピングの基本パターンについて整理しました。テンプレートの書き方や、find / find_all の使い分け、class や id を使った絞り込み、ブロック単位での処理など、実際にコードを書くための土台を確認しました。今回は、その続きとして、複数ページにまたがる情報を取得する方法、いわゆる「ページネーション(pagination)」について解説することにしましょう。

実際のWebサイトでは、情報が1ページに収まっていることは少なく、

  • 商品一覧(1ページ目、2ページ目…)
  • ニュース記事一覧(次へ、前へ)
  • 検索結果ページ

といったように、複数ページに分割されているケースが一般的です。スクレイピングを実務で使う場合、この「ページをまたぐ処理」ができるかどうかで、取得できるデータ量が大きく変わってきます。

今回も教科書『Pythonによる新しいデータ分析の教科書(第2版)』では「スクレイピング」(274ページ〜284ページ)の続きにあたる部分です。

ページネーションとは何か

ページネーションとは、データを複数ページに分割して表示する仕組みのことです。

たとえば、商品一覧ページであれば、

  • 1ページ目:1〜20件
  • 2ページ目:21〜40件
  • 3ページ目:41〜60件

といった形で分割されています。ブラウザ上では「次へ」ボタンをクリックするだけですが、スクレイピングではこの遷移をプログラムで再現する必要があります。

URLの変化を確認する

ページネーションを扱う際に、まずやるべきことは「URLの変化を確認する」ことです。

たとえば、次のようなURLを見てみます。

https://example.com/items?page=1
https://example.com/items?page=2
https://example.com/items?page=3

このように、ページ番号がURLのパラメータとして変化している場合、非常に扱いやすいです。この場合、Pythonでは単純にループでページ番号を回すことができます。

ページをループして取得する

実際のコード例を見てみましょう。

import requests
from bs4 import BeautifulSoup

for page in range(1, 4):
    url = f”https://example.com/items?page={page}”
    response = requests.get(url)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, “html.parser”)

    items = soup.find_all(“div”, class_=”item”)

    for item in items:
        name = item.find(“h2”).text.strip()
        print(name)

このコードでは、

  • ページ番号を1〜3までループ
  • 各ページのHTMLを取得
  • BeautifulSoupで解析
  • 各ページのデータを取り出す

という処理を繰り返しています。前回紹介した「ブロック単位で処理する」考え方が、そのまま使われていることが分かると思います。

「次へ」リンクをたどる方法

しかし、すべてのサイトが「?page=1」のような分かりやすいURLとは限りません。その場合は、「次へ」リンクをたどる方法を使います。

url = “https://example.com/items”

while url:
    response = requests.get(url)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, “html.parser”)

    items = soup.find_all(“div”, class_=”item”)

    for item in items:
        name = item.find(“h2”).text.strip()
        print(name)

    next_link = soup.find(“a”, class_=”next”)
    if next_link:
        url = next_link.get(“href”)
    else:
        url = None

この方法では、

  • 現在のページを取得
  • 「次へ」リンクを探す
  • リンクがあれば次のページへ進む
  • なければ終了

という流れになります。実務では、こちらの方法が必要になるケースが多いかもしれません。

ページネーションで気をつけるポイント

ページネーションを扱う際には、いくつか注意点があります。

まず、無限ループに注意することです。「次へ」リンクの取得がうまくいかない場合、同じページを何度も取得してしまうことがあります。ループ条件は必ず確認しましょう。

次に、アクセス回数の制御です。短時間に大量のリクエストを送ると、サイトに負荷をかけたり、アクセス制限を受けたりする可能性があります。

import time
time.sleep(1)

のように、1秒程度の待機を入れるだけでも、かなり安全性が高まります。

また、ページ数の上限を決めることも重要です。すべてのページを取得する必要があるのか、それとも一定範囲でよいのかを事前に考えておくと、無駄な処理を防ぐことができます。

今回のまとめ

今回は、スクレイピングにおいて重要な「ページネーション」の扱いについて解説しました。

ポイントは次のとおりです。

  • Webサイトの多くは複数ページに分割されている
  • URLの変化を確認すると実装しやすい
  • ループ処理で複数ページを取得できる
  • 「次へ」リンクをたどる方法もある
  • アクセス間隔やループ条件に注意する

これまでの内容と組み合わせることで、

  • 1ページの情報を取得する
  • 複数ページに展開する

という、実務に近いスクレイピングができるようになってきました。

次回は、この取得したデータを整理し、pandasと連携して、CSVやExcelに出力する方法について解説していきます。データとして扱える形に整えることで、分析や共有が一気にしやすくなります。次回もお楽しみに。

PAGE TOP