はじめに
「あのサイトの情報を毎日チェックするのが面倒…」「複数サイトの価格を自動で比較できないかな?」
このような悩みを持ったことはありませんか?実は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のどこにあるかを知ることが重要です。その調査方法を見ていきましょう。
ブラウザの開発者ツールを使う
- Chromeブラウザでtenki.jpを開く
- 取得したい情報(例:今日の天気)の上で右クリック
- 「検証」または「要素を調査」を選択
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℃
コードの解説
requests.get(url): 指定したURLのWebページを取得しますBeautifulSoup(res.text, "html.parser"): HTMLを解析できる形に変換しますsoup.find("div", class_="today-weather"): 天気情報が含まれる要素を探します.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サイトのスクレイピング手法
この記事はいかがでしたか?質問やご感想があれば、コメント欄でお待ちしています!


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