競合の価格チェック、ニュースの収集、公開データの転記など、「Webサイトを見て、情報をExcelに写す」作業は意外と多くの職場にあります。この作業はPythonのスクレイピングで自動化できます。この記事では、Webページの表を取得してExcelファイルに出力するところまでを、実際に動くコードで解説します。
先に確認:スクレイピングの注意点
スクレイピングは便利ですが、やり方を間違えるとトラブルになります。始める前に、次の4点を必ず確認してください。
- 利用規約を確認する:サイトによってはスクレイピングを禁止しています。規約に禁止の記載がないか、先に読んでください。
- robots.txtを確認する:
https://対象サイト/robots.txt を開くと、取得してよいページ・いけないページが書かれています。
- サーバーに負荷をかけない:短時間に大量のアクセスを送ると、相手サイトの迷惑になります。リクエストの間隔を空ける処理を必ず入れましょう。
- APIがあるならAPIを使う:公式にAPIや配布データ(CSVなど)が提供されている場合は、そちらを使うのが最も安全で確実です。
使うライブラリ
pip install requests beautifulsoup4 pandas openpyxl lxml
- requests:WebページのHTMLを取得する
- BeautifulSoup:取得したHTMLから必要な部分を取り出す
- pandas / openpyxl:取り出したデータを表にして、Excelに出力する
基本の考え方
- 対象のURLにアクセスして、HTMLを取得する
- HTMLの中から、欲しい情報(表やリスト)を取り出す
- 取り出したデータを表にして、Excelファイルに出力する
サンプルコード1:ページ内の表をそのままExcelにする
対象ページにHTMLの表(`
`タグ)がある場合は、pandasの`read_html`が最も簡単です。
“`python
import pandas as pd
import requests
from io import StringIO
url = “https://example.com/data” # 取得したいページのURLに置き換える
headers = {“User-Agent”: “Mozilla/5.0 (業務効率化のための個人利用)”}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # エラーなら、ここで止める
# ページ内のすべての表を取得(結果はリストで返る)
tables = pd.read_html(StringIO(response.text))
print(f”{len(tables)}個の表が見つかりました”)
# 1つ目の表をExcelに出力
tables[0].to_excel(“取得結果.xlsx”, index=False)
“`
**ポイント解説**
– `response.raise_for_status()`:アクセスに失敗(404や500など)した場合に、その場でエラーにして気づけるようにします。
– `pd.read_html(…)`:HTMLの中にある`
`をすべて探して、表(DataFrame)のリストにしてくれます。どの表が必要かは、`tables[0]`、`tables[1]`と番号で選びます。
– `timeout=10`:応答がないときに、いつまでも待ち続けないための設定です。
## サンプルコード2:記事一覧などのテキストを取り出す
表ではなく、ニュース一覧のようなリスト形式の情報を取りたい場合は、BeautifulSoupで取り出します。
“`python
import time
import pandas as pd
import requests
from bs4 import BeautifulSoup
url = “https://example.com/news” # 対象ページに置き換える
headers = {“User-Agent”: “Mozilla/5.0 (業務効率化のための個人利用)”}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
response.encoding = response.apparent_encoding # 文字化け対策
soup = BeautifulSoup(response.text, “lxml”)
rows = []
# 「class=”news-item”」を持つ要素を、すべて取り出す(実際のサイトに合わせて変更)
for item in soup.select(“.news-item”):
title = item.select_one(“.title”).get_text(strip=True)
link = item.select_one(“a”)[“href”]
rows.append({“タイトル”: title, “URL”: link})
df = pd.DataFrame(rows)
df.to_excel(“ニュース一覧.xlsx”, index=False)
time.sleep(1) # 複数ページを回すときは、1秒以上の間隔を空ける
print(f”{len(df)}件を取得しました”)
“`
**ポイント解説**
– `soup.select(“.news-item”)`:CSSセレクタで、欲しい要素を指定します。実際のサイトのHTMLに合わせて書き換えるのが、一番の作業ポイントです。
– `get_text(strip=True)`:タグを除いた文字だけを取り出し、前後の空白も削ります。
– `time.sleep(1)`:アクセスの間隔を空けるための処理です。複数ページを順に取得するときは、ループの中に必ず入れてください。
## セレクタの調べ方
欲しい情報がHTMLのどこにあるかは、ブラウザで調べられます。
1. 対象のページをブラウザで開く
2. 取りたい文字の上で右クリック→「検証」(Chromeの場合)
3. 表示されるHTMLの中で、その文字を囲んでいるタグの`class`名を確認する
4. その`class`名を、上のコードの`select(…)`に当てはめる
## よくあるつまずきポイント
– **文字化けする**:`response.encoding = response.apparent_encoding`を入れると直ることが多いです。
– **取得できるはずの情報が空になる**:ページの内容がJavaScriptで後から表示されるサイトでは、requestsでは取得できません。その場合は、Seleniumなどブラウザを操作するライブラリが必要になります。
– **アクセスを拒否される(403エラー)**:`User-Agent`が空だと弾かれるサイトがあります。ただし、拒否されるのは取得を望まれていない可能性もあるので、無理に回避するのは避け、利用規約を再確認してください。
– **サイトの構造が変わって動かなくなる**:スクレイピングは、相手サイトのHTMLが変わると動かなくなります。定期実行するなら、エラー時に気づける仕組み(メール通知など)を入れておくと安心です。
## 他の自動化と組み合わせる
取得したデータは、そのまま次の作業につなげられます。
– 取得結果を、[複数ファイルの集計](https://www.excel-python-jido.com/excel-shukei-jido/)の処理に流して、他のデータと合算する
– 集計結果を、[定型フォーマットに自動転記](https://www.excel-python-jido.com/excel-tenki-jido/)して、報告書にする
「取得→集計→転記」までつなげれば、毎週の情報収集レポートも、スクリプトの実行だけで完成します。
## まとめ
スクレイピングは、requestsでHTMLを取得し、pandasやBeautifulSoupで必要な部分を取り出し、Excelに出力するという流れで実現できます。ただし、利用規約の確認とアクセス間隔の配慮は必須です。ルールを守った上で、日々のWeb確認作業を自動化してみてください。
コメント