Pythonスクレイピング入門!requestsとBeautifulSoup4で実データ収集を自動化する方法
「Webサイトのデータを自動で集めたい…でも、スクレイピングってなんだか難しそう」
そんなふうに感じている方、多いんじゃないでしょうか。
実は、Pythonには requests と BeautifulSoup4 という2つのライブラリを組み合わせるだけで、Webサイトのデータを自動収集できる仕組みが整っています。コードの量もびっくりするくらい少なくて済むんですよね。
この記事では、スクレイピングが初めての方でもつまずかないよう、環境構築→HTMLの読み方→データ抽出→CSV保存までを一気に解説します。ざっくりした全体像がつかめるはずなので、ぜひ最後まで読んでみてください! 🐍
📌 この記事の対象者と難易度

- ✅ Pythonの基本文法(for文・関数・リスト)がわかる方
- ✅ HTMLのタグをなんとなく知っている方
- ✅ Webサイトのデータを自動収集してみたい方
- 🔰 難易度:初〜中級者向け
逆に「Pythonって何?」という完全未経験の方は、まず基本文法を押さえてからこの記事に戻ってくると、スムーズに理解できると思います。
🕸️ スクレイピングとは?まず概念をざっくり理解しよう
スクレイピング(Web Scraping)とは、WebサイトのHTMLを自動で取得して、必要な情報だけを取り出す技術のことです。
イメージとしては、こんな感じです。
- ブラウザがやること → URLを開いてHTMLを受け取り、見やすく表示する
- スクレイピングがやること → URLを開いてHTMLを受け取り、必要なテキストだけを抜き出す
人間が目でやっていた「コピペ作業」を、Pythonが自動でやってくれるイメージです。ニュースの見出しを毎日集めたり、商品の価格を定期的に記録したりと、応用範囲はとても広いですよ。
ただし、スクレイピングには注意点もあります。利用規約で禁止しているサイトへのアクセスや、サーバーに過度な負荷をかける行為は絶対にNGです。必ず利用規約を確認し、適切な間隔(1秒以上)を空けてアクセスするようにしましょう。
🛠️ 環境構築:2つのライブラリをインストールする
まずは必要なライブラリをインストールします。ターミナル(コマンドプロンプト)を開いて、以下を実行してください。
pip install requests beautifulsoup4
これだけです! 2つのライブラリの役割をざっくり説明するとこんな感じです。
- requests:URLを指定してHTMLをまるごとダウンロードするライブラリ
- BeautifulSoup4:ダウンロードしたHTMLを解析して、特定のタグや要素を取り出すライブラリ
requestsで「HTML素材」を取ってきて、BeautifulSoup4で「必要な部分を切り出す」という役割分担になっています。
📥 STEP 1:requestsでHTMLを取得する
まず、requestsを使ってWebページのHTMLを取得する基本コードを見てみましょう。
import requests
# HTMLを取得したいURLを指定
url = "https://books.toscrape.com/"
# GETリクエストを送ってレスポンスを受け取る
response = requests.get(url)
# ステータスコードを確認(200なら成功)
print(response.status_code)
# 取得したHTMLの最初の500文字だけ表示
print(response.text[:500])
ここでのポイントをまとめるとこんな感じです。
- requests.get(url):指定したURLにHTTPリクエストを送る
- response.status_code:200なら取得成功。404はページなし、403はアクセス拒否
- response.text:取得したHTMLが文字列として入っている
今回の練習では books.toscrape.com を使います。これはスクレイピング練習専用に作られた公式の練習サイトなので、安心して使えますよ 🎉
🔍 STEP 2:BeautifulSoup4でHTMLを解析する
取得したHTMLをそのまま扱うのは大変です。BeautifulSoup4を使うと、特定のタグや要素をかんたんに抽出できます。
import requests
from bs4 import BeautifulSoup
url = "https://books.toscrape.com/"
response = requests.get(url)
# BeautifulSoupオブジェクトを作成
# html.parser はPython標準のHTMLパーサー
soup = BeautifulSoup(response.text, "html.parser")
# ページのタイトルを取得
print(soup.title.text)
# h3タグをすべて取得してみる
h3_tags = soup.find_all("h3")
print(f"h3タグの数: {len(h3_tags)}")
# 最初のh3タグの中身を表示
print(h3_tags[0].text)
BeautifulSoup(response.text, "html.parser") の部分は、HTMLをパース(解析)するおまじないだと思っておけばOKです。
主要なメソッドはこの2つを押さえておきましょう。
- soup.find(“タグ名”):条件に一致する最初の1つだけ取得
- soup.find_all(“タグ名”):条件に一致するすべてを取得してリストで返す
🎯 STEP 3:CSSクラスを使って狙ったデータだけ取り出す
実際のWebサイトでは、同じタグが何十個もあります。そのうち特定のデータだけを取り出すには、CSSクラス名を条件として使うのが定番です。
まず、ブラウザの「検証(デベロッパーツール)」でどんなクラス名が使われているか確認するのが最初のステップです。Chromeなら F12 キーを押すと開きます。
import requests
from bs4 import BeautifulSoup
url = "https://books.toscrape.com/"
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
# class="product_pod" を持つdivタグをすべて取得(1冊分のブロック)
books = soup.find_all("article", class_="product_pod")
print(f"取得した本の数: {len(books)}")
# 最初の1冊のタイトルと価格を取り出す
first_book = books[0]
# タイトルはh3タグのaタグのtitle属性に入っている
title = first_book.h3.a["title"]
# 価格はclass="price_color"のpタグに入っている
price = first_book.find("p", class_="price_color").text
print(f"タイトル: {title}")
print(f"価格: {price}")
ここが重要です!
- class_=「クラス名」(アンダースコア付き):Pythonの予約語と区別するためのBeautifulSoup独自の書き方
- タグ[“属性名”]:属性の値を取り出す書き方(例:
a["href"]でリンク先URLを取得) - .text:タグの中のテキストだけを取り出すプロパティ
🔄 STEP 4:複数ページのデータをループで収集する
実用的なスクレイピングでは、1ページだけでなく複数ページにまたがってデータを集めることが多いですよね。books.toscrape.com には50ページ分の本データがあるので、複数ページを自動で巡回してみましょう。
import requests
from bs4 import BeautifulSoup
import time # サーバーへの負荷軽減のために使う
base_url = "https://books.toscrape.com/catalogue/page-{}.html"
all_books = [] # 収集したデータを入れるリスト
# 最初の3ページ分だけ収集(練習なので少なめに)
for page_num in range(1, 4):
url = base_url.format(page_num)
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
books = soup.find_all("article", class_="product_pod")
for book in books:
title = book.h3.a["title"]
price = book.find("p", class_="price_color").text.strip()
# 評価(星の数)はclass名に含まれている
rating_tag = book.find("p", class_="star-rating")
rating = rating_tag["class"][1] # 例: "Three"
all_books.append({
"title": title,
"price": price,
"rating": rating
})
print(f"ページ {page_num} 完了 → {len(books)}件取得")
# 1秒待機してサーバーへの負荷を下げる(マナー!)
time.sleep(1)
print(f"\n合計 {len(all_books)} 件のデータを取得しました")
time.sleep(1) は地味に見えますが、スクレイピングにおける大事なマナーです。リクエストを連発するとサーバーに迷惑がかかるので、必ず入れるようにしましょう。
💾 STEP 5:収集したデータをCSVに保存する
せっかく集めたデータは、CSVファイルに保存してExcelやpandasで活用できるようにしましょう。Pythonの標準ライブラリ csv を使えば、追加インストールなしで保存できます。
import csv
# 保存するファイル名
filename = "books_data.csv"
# CSVファイルに書き込む
with open(filename, "w", newline="", encoding="utf-8-sig") as f:
# 列名(ヘッダー)を定義
fieldnames = ["title", "price", "rating"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
# ヘッダー行を書き込む
writer.writeheader()
# all_books リストの各辞書を1行ずつ書き込む
writer.writerows(all_books)
print(f"✅ {filename} に保存完了!")
encoding="utf-8-sig" にしているのが地味なポイントです。utf-8-sig にしておくと、Windowsで開いたときに文字化けが防げます。ここは忘れやすいので覚えておいてください。
🧩 全コードをまとめて確認しよう
ここまでのコードを1ファイルにまとめると、こんな完成形になります。
import requests
from bs4 import BeautifulSoup
import time
import csv
def scrape_books(max_pages=3):
"""books.toscrape.com から本のデータを収集してCSVに保存する関数"""
base_url = "https://books.toscrape.com/catalogue/page-{}.html"
all_books = []
for page_num in range(1, max_pages + 1):
url = base_url.format(page_num)
# リクエスト送信
response = requests.get(url)
# ステータスコードの確認
if response.status_code != 200:
print(f"ページ {page_num} の取得に失敗: {response.status_code}")
break
soup = BeautifulSoup(response.text, "html.parser")
books = soup.find_all("article", class_="product_pod")
for book in books:
title = book.h3.a["title"]
price = book.find("p", class_="price_color").text.strip()
rating = book.find("p", class_="star-rating")["class"][1]
all_books.append({
"title": title,
"price": price,
"rating": rating
})
print(f"ページ {page_num} → {len(books)}件取得")
time.sleep(1) # サーバーへの負荷軽減
# CSVに保存
filename = "books_data.csv"
with open(filename, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["title", "price", "rating"])
writer.writeheader()
writer.writerows(all_books)
print(f"\n✅ 合計 {len(all_books)} 件を {filename} に保存しました!")
return all_books
if __name__ == "__main__":
scrape_books(max_pages=3)
ポイントをまとめるとこんな感じです。
- ✅ 処理を 関数 にまとめて再利用しやすくした
- ✅ ステータスコードをチェックして異常時に処理を止める
- ✅
if __name__ == "__main__":でスクリプトとして実行できる構成にした
⚠️ スクレイピングをする前に必ず確認すること
スクレイピングは強力な技術ですが、正しく使うことが大前提です。実際のサイトに適用する前に、以下を必ずチェックしてください。
- 📄 利用規約(Terms of Service)の確認:スクレイピングを禁止しているサイトは多いです
- 🤖 robots.txt の確認:
https://サイトURL/robots.txtにアクセスすると、クローラーの許可範囲がわかります - ⏱️ アクセス間隔を空ける:最低でも1秒以上。できれば3〜5秒
- 🚫 ログインが必要なページ・個人情報を含むページ:スクレイピングはしない
- 📦 APIが提供されているなら優先的に使う:APIがある場合はそちらを使いましょう
「技術的にできる」と「やっていい」は別の話です。ルールを守って活用しましょう!
🚀 よくあるエラーと対処法
スクレイピングで初心者がよく詰まるポイントをまとめておきます。
① UnicodeDecodeError が出る
HTMLの文字コードがうまく認識されていないケースです。response.encoding = "utf-8" を requests.get() の直後に追加してみてください。または response.content をBeautifulSoupに渡すと自動で判定してくれます。
② 期待したデータが取れない・None が返ってくる
find() で見つからなかったときに None が返ります。デベロッパーツールで実際のHTMLを再確認しましょう。JavaScriptで動的に生成されているコンテンツは、requestsでは取得できません(その場合はSeleniumやPlaywrightが必要になります)。
③ 403 Forbidden エラーが出る
サーバーがボットからのアクセスをブロックしているケースです。Headerに User-Agent を設定することで回避できる場合があります。
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(url, headers=headers)
ただし、そもそもスクレイピングが禁止されているサイトの場合は、User-Agentを変えても使用は控えましょう。
📝 まとめ
今回の内容をまとめると、こんな感じです。
- ✅ requests でWebページのHTMLをダウンロードする
- ✅ BeautifulSoup4 で必要なタグ・クラスのデータを抽出する
- ✅ ループ で複数ページのデータを自動収集する
- ✅ csv モジュールでデータをCSVファイルに保存する
- ✅ スクレイピングには利用規約・robots.txtの確認、アクセス間隔の設定が必須
requestsとBeautifulSoup4の組み合わせは、シンプルなスクレイピングの定番中の定番です。「なんだかむずかしそう」と思っていたスクレイピングが、少し身近に感じられたんじゃないでしょうか。
まずは今回使った books.toscrape.com で実際にコードを動かしてみることをおすすめします。手を動かすと一気に理解が深まりますよ 💪
次のステップとしては、pandasと組み合わせてデータを分析する方法や、JavaScriptで動くサイトに対応するための Playwright を使ったスクレイピングにも挑戦してみてください。一緒に学んでいきましょう!
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





