【初心者向け】PythonでWebスクレイピング入門|BeautifulSoupの使い方を徹底解説

目次

はじめに

「あのサイトの情報を毎日チェックするのが面倒…」「複数サイトの価格を自動で比較できないかな?」

このような悩みを持ったことはありませんか?実はPythonを使えば、Webサイトから自動で情報を取得する「Webスクレイピング」が簡単にできるんです!

本記事では、プログラミング初心者の方でも理解できるよう、Pythonでのスクレイピングの基本を丁寧に解説します。この記事を読めば、天気予報サイトからデータを取得してCSVファイルに保存するところまで、実践的なスキルが身につきます。

今やビジネスでもプライベートでも、データ収集の自動化は大きな武器になります。一緒に学んでいきましょう!

Webスクレイピングとは?

データ収集の自動化

Webスクレイピングとは、Webサイトから自動的にデータを抽出する技術です。人間がブラウザでWebページを見て情報を得るように、プログラムがWebページの内容を読み取り、必要な情報だけを取り出します。

スクレイピングが使われる具体例

  • ニュースの自動収集: 複数のニュースサイトから最新記事を収集
  • 天気予報の取得: 毎朝の天気予報を自動でチェック
  • EC価格比較: 複数サイトの商品価格を自動比較
  • 研究データ収集: 論文や統計データの自動収集

クローリングとの違い

初心者がよく混同するのが「クローリング」と「スクレイピング」です。

  • クローリング: Webサイトのリンクをたどって次々とページを巡回する技術
  • スクレイピング: Webページから特定の情報を抽出する技術

簡単に言えば、クローリングは「ページを次々と訪問すること」、スクレイピングは「ページから情報を取り出すこと」です。この記事では主にスクレイピングに焦点を当てますが、応用編では簡単なクローリングも紹介します。

準備

Python環境の準備

本記事ではPythonがインストール済みであることを前提としています。まだの方はPython公式サイトからダウンロードしてインストールしてください。

エディタは以下のいずれかがおすすめです:

  • VSCode: 無料で高機能なコードエディタ
  • Jupyter Notebook: 初心者にも使いやすいインタラクティブな環境

必要なライブラリのインストール

スクレイピングに必要な2つのライブラリをインストールします。コマンドプロンプト(Windowsの場合)またはターミナル(MacやLinuxの場合)で以下のコマンドを実行してください

pip install requests
pip install beautifulsoup4

それぞれのライブラリの役割は:

  • requests: WebサイトのHTMLを取得するライブラリ
  • BeautifulSoup: HTML文書を解析して必要な情報を抽出するライブラリ

これだけで準備完了です!

実践:天気予報サイトをスクレイピングしてみよう!

ターゲットページの選定

実践例として、tenki.jpの東京の天気予報ページからデータを取得してみましょう。
(※実際のスクレイピングを行う際は、各サイトの利用規約を必ず確認してください)

今回使用するURL:https://tenki.jp/forecast/3/16/4410/13113/

HTML構造の調査

スクレイピングでは、目的の情報がHTMLのどこにあるかを知ることが重要です。その調査方法を見ていきましょう。

ブラウザの開発者ツールを使う

  1. Chromeブラウザでtenki.jpを開く
  2. 取得したい情報(例:今日の天気)の上で右クリック
  3. 「検証」または「要素を調査」を選択

CTRL+Fで以下のようなHTMLコードを探します:

<div class="forecast-days-wrap">
  <p class="weather-telop">晴れ</p>
  <dl class="date-value">
    <dt class="high-temp sumarry">最高</dt>
    <dd class="high-temp temp"><span class="value">25</span><span class="unit">℃</span></dd>
    <dd class="high-temp tempdiff">[+5]</dd>
    <dt class="low-temp sumarry">最低</dt>
    <dd class="low-temp temp"><span class="value">10</span><span class="unit">℃</span></dd>
    <dd class="low-temp tempdiff">[+2]</dd>
  </dl>
</div>

これで、取得したい情報のタグ名(div)とクラス名(today-weather)がわかりました。

スクレイピング基本コード

それでは実際にコードを書いていきましょう!

import requests
from bs4 import BeautifulSoup

# 天気予報サイトのURL
url = "https://tenki.jp/forecast/3/16/4410/13113/"

# 1. Webページの取得
res = requests.get(url)

# 文字化けを防ぐためにエンコーディングを指定
res.encoding = res.apparent_encoding

# 2. BeautifulSoupオブジェクトの作成
soup = BeautifulSoup(res.text, "html.parser")

# 3. 今日の天気を取得
today_weather = soup.find("div", class_="forecast-days-wrap")
weather_telop = today_weather.find("p", class_="weather-telop").text  # 天気(晴れ、曇りなど)
high_temp = today_weather.find("dl", class_="date-value").find("dd", class_="high-temp temp").find("span", class_="value").text
low_temp = today_weather.find("dl", class_="date-value").find("dd", class_="low-temp temp").find("span", class_="value").text

# 4. 結果を表示
print(f"今日の天気: {weather_telop}")
print(f"最高気温: {high_temp}℃")
print(f"最低気温: {low_temp}℃")

このコードを実行すると、以下のような結果が表示されます:

今日の天気: 晴れ
最高気温: 26℃
最低気温: 18℃

コードの解説

  1. requests.get(url): 指定したURLのWebページを取得します
  2. BeautifulSoup(res.text, "html.parser"): HTMLを解析できる形に変換します
  3. soup.find("div", class_="today-weather"): 天気情報が含まれる要素を探します
  4. .text: テキスト部分だけを抽出します

取得した情報の整形・保存

取得したデータを整形し、CSVファイルとして保存してみましょう。

import requests
from bs4 import BeautifulSoup
import csv
from datetime import datetime

# 天気予報サイトのURL
url = "https://tenki.jp/forecast/3/16/4410/13113/"

# Webページの取得と解析
res = requests.get(url)
res.encoding = res.apparent_encoding
soup = BeautifulSoup(res.text, "html.parser")

# 今日の天気を取得
today_weather = soup.find("div", class_="forecast-days-wrap")
weather_telop = today_weather.find("p", class_="weather-telop").text.strip()
high_temp = today_weather.find("dl", class_="date-value").find("dd", class_="high-temp temp").find("span", class_="value").text.strip()
low_temp = today_weather.find("dl", class_="date-value").find("dd", class_="low-temp temp").find("span", class_="value").text.strip()

# 日付を取得
today = datetime.now().strftime("%Y-%m-%d")

# CSVファイルに保存
with open('weather_data.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['日付', '天気', '最高気温', '最低気温'])
    writer.writerow([today, weather_telop, high_temp, low_temp])

print("データをCSVファイルに保存しました。")

このコードでは、.strip()メソッドを使って余分な空白を削除し、CSVファイルに保存しています。

発展:pandasを使ったCSV保存

pandasライブラリを使うとさらに簡単にデータを扱えます!

import pandas as pd

# データフレームの作成
weather_data = pd.DataFrame({
    '日付': [today],
    '天気': [weather_telop],
    '最高気温': [high_temp],
    '最低気温': [low_temp]
})

# CSVファイルに保存
weather_data.to_csv('weather_data.csv', index=False, encoding='utf-8')

応用:複数ページのデータ取得

import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime

# 地域とURLのマッピング
areas = {
    '東京': 'https://tenki.jp/forecast/3/16/4410/13113/',
    '大阪': 'https://tenki.jp/forecast/6/30/6200/27100/',
    '札幌': 'https://tenki.jp/forecast/1/2/1400/1100/',
    '福岡': 'https://tenki.jp/forecast/9/43/8210/40130/'
}

# 結果を格納するリスト
results = []

# 現在の日付
today = datetime.now().strftime("%Y-%m-%d")

# 各地域の天気を取得
for area_name, url in areas.items():
    # Webページの取得と解析
    res = requests.get(url)
    res.encoding = res.apparent_encoding
    soup = BeautifulSoup(res.text, "html.parser")
    
    # 今日の天気を取得
    today_weather = soup.find("div", class_="today-weather")
    weather_telop = today_weather.find("p", class_="weather-telop").text.strip()
    high_temp = today_weather.find("p", class_="high-temp").find("span", class_="value").text.strip()
    low_temp = today_weather.find("p", class_="low-temp").find("span", class_="value").text.strip()
    
    # 結果をリストに追加
    results.append([today, area_name, weather_telop, high_temp, low_temp])
    
    # サーバーに負荷をかけないよう1秒待機
    import time
    time.sleep(1)

# DataFrameに変換
df = pd.DataFrame(results, columns=['日付', '地域', '天気', '最高気温', '最低気温'])

# CSVファイルに保存
df.to_csv('weather_multiple_areas.csv', index=False, encoding='utf-8')

print("複数地域の天気データをCSVファイルに保存しました。")

このコードでは、地域とURLの辞書を作成し、forループで各地域の天気を取得しています。また、サーバーに負荷をかけないようtime.sleep(1)で1秒間の待機を入れています。

スクレイピングの注意点とマナー

スクレイピングは便利ですが、いくつか守るべきマナーがあります。

アクセス頻度を抑える

短時間に多数のリクエストを送ると、サーバーに負荷をかけてしまいます。time.sleep()を使って、リクエスト間に適切な間隔を設けましょう

import time

# リクエストごとに1秒待機
time.sleep(1)

利用規約の確認

スクレイピングを行う前に、必ずサイトの利用規約を確認してください。多くのサイトではスクレイピングに関する規定があります。

APIがある場合はそちらを使う

多くのサービス(Twitter、GitHub、天気予報サイトなど)では公式APIを提供しています。APIがある場合は、スクレイピングよりもAPIを使用する方が望ましいです。

よくあるエラーと対処法

403 Forbidden:User-Agentの設定

一部のサイトでは、普通のブラウザからのアクセスのみを許可しています。この場合、User-Agentを設定することで解決できます:

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
res = requests.get(url, headers=headers)

タグが見つからない:HTML構造の変更対応

Webサイトのデザインが変更されると、HTMLの構造も変わることがあります。エラーが発生した場合は、開発者ツールで再度HTML構造を確認してください。

# エラーを防ぐための例外処理
try:
    weather_telop = today_weather.find("p", class_="weather-telop").text
except AttributeError:
    weather_telop = "取得できませんでした"

ページがJavaScriptで描画されている

JavaScriptで動的に生成されるコンテンツは、requestsだけでは取得できません。このような場合は、SeleniumやPlaywrightといったブラウザ自動化ツールを使用します。

# Seleniumの基本的な使い方(参考)
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")

詳細は「Python × Selenium入門」の記事で解説しています

まとめ

この記事では、Pythonを使ったWebスクレイピングの基礎を学びました:

  • 準備するもの: Pythonと必要なライブラリ(requestsとBeautifulSoup)
  • 基本的な流れ: URLからHTMLを取得→解析→必要なデータを抽出
  • 実践例: 天気予報サイトからデータを取得してCSVに保存
  • 応用: 複数ページからのデータ取得
  • マナーと注意点: アクセス頻度の調整など

初心者の方でも、この記事の内容を実践すれば、1日でスクレイピングの基本が身につきます。実際にやってみると、思ったより簡単なはずです!

次のステップとしては、SeleniumやPlaywrightを使った動的コンテンツのスクレイピングや、pandasを使ったデータ分析・可視化に挑戦してみてください。

【関連記事リンク】

  • Python × pandas入門:データ分析の基礎を学ぼう
  • Pythonで作る自動レポート:ビジネスを効率化する方法
  • Selenium入門:動的Webサイトのスクレイピング手法

この記事はいかがでしたか?質問やご感想があれば、コメント欄でお待ちしています!

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメントやリクエストがあったら教えてね!

コメントする

目次