Day 53:Webデータ取得 ― 「情報収集ツール」を作りながら、正しいマナーも身につける
Day 53では、Pythonで Web上の公開情報を集める「情報収集ツール」 を作りながら、 技術だけでなく、利用規約・robots.txt・アクセス制限を確認する習慣 もセットで身につけていきます。
ここまで学んできた「HTTP」「requests」「Beautiful Soup」を組み合わせて、 実際に「Webデータ取得の一連の流れ」を体験する回です。
Webデータ取得の全体像をイメージする
情報収集ツールの役割を言葉で整理する
まずは、今日作る 情報収集ツール の役割を、ざっくり言葉で整理してみます。
- 公開されているWebページから情報を取得する
- HTMLを解析して、欲しい部分(タイトル・本文・リンクなど)を抜き出す
- 結果を画面に表示したり、ファイルに保存したりできるようにする
- その前提として、利用規約・robots.txt・アクセス制限を確認する習慣を持つ
技術的には、
requestsでHTMLを取得BeautifulSoupでHTMLを解析- タグ・属性・CSSセレクタで要素を検索
- テキストやリンクを抽出
という流れになります。
Webデータ取得のマナー:利用規約・robots.txt・アクセス制限
なぜ「マナー」が重要なのか
Webデータ取得は、技術的には「できてしまう」ことが多いですが、 だからこそ 「やっていいかどうか」 を常に意識する必要があります。
特に意識したいのは次の3つです。
- 利用規約(Terms of Service)
- robots.txt
- アクセス制限(レート制限・認証など)
利用規約を確認する習慣
多くのサイトには「利用規約」や「ご利用条件」があり、 そこに「スクレイピング禁止」「自動取得禁止」などの記載がある場合があります。
情報収集ツールを作るときは、
「このサイトは、自動取得を許可しているか?」
を必ず確認する習慣を持つことが大切です。
robots.txtを確認する習慣
robots.txt は、サイトのトップに置かれる「クローラー向けのルール」です。
例:https://example.com/robots.txt
ここには、
- どのパスへのアクセスを許可するか
- どのパスへのアクセスを禁止するか
といった情報が書かれています。
情報収集ツールを作るときは、
「robots.txtで禁止されているパスにはアクセスしない」
というルールを守ることが基本になります。
アクセス制限・レート制限を意識する
APIと同様、Webサイトにも「短時間に大量アクセスすると制限される」仕組みがあることがあります。
- 一定時間に何回まで
- 一度に大量のページを取得しない
- 適度な間隔を空ける
といった配慮をすることで、
「サイトに迷惑をかけない情報収集」
を心がけることができます。
ステップ1:HTMLを取得する小さな関数を作る
まずは、情報収集ツールの「入口」となる、 HTML取得関数 を作っていきます。
# day53_web_fetch.py
import requests
def fetch_html(url: str) -> str | None:
"""
指定したURLからHTMLを取得する関数です。
- 公開情報を対象にします。
- タイムアウトやHTTPエラーを簡単に扱います。
"""
print(f"[GET] {url} にアクセスします。")
try:
# timeout= を付けて、いつまでも待たないようにします。
response = requests.get(url, timeout=5)
except requests.exceptions.RequestException as e:
# ネットワークエラーなどをまとめて扱います。
print("HTML取得中にエラーが発生しました:", e)
return None
# ステータスコードをチェックします。
if 200 <= response.status_code < 300:
# 成功した場合は、レスポンス本文(HTML)を返します。
return response.text
else:
print("HTMLの取得に失敗しました。ステータスコード:", response.status_code)
return None
if __name__ == "__main__":
# 練習用に httpbin のHTMLページを取得してみます。
url = "https://httpbin.org/html"
html = fetch_html(url)
if html is not None:
print("取得したHTMLの先頭100文字:")
print(html[:100])
Pythonここではまだ「HTML文字列」を手に入れただけですが、 次のステップでこれを解析して「情報収集ツール」に近づけていきます。
ステップ2:Beautiful SoupでHTMLを解析し、情報を抜き出す
タイトル・本文・リンクを抽出する基本パターン
次に、Beautiful Soupを使って、 HTMLから「欲しい情報」を抜き出す処理を書いていきます。
# day53_info_extractor.py
import requests
from bs4 import BeautifulSoup
def fetch_html(url: str) -> str | None:
"""Day 53用のHTML取得関数です。"""
print(f"[GET] {url} にアクセスします。")
try:
response = requests.get(url, timeout=5)
except requests.exceptions.RequestException as e:
print("HTML取得中にエラーが発生しました:", e)
return None
if 200 <= response.status_code < 300:
return response.text
else:
print("HTMLの取得に失敗しました。ステータスコード:", response.status_code)
return None
def extract_info(html: str):
"""
HTMLから情報を抽出する関数です。
- ページタイトル(<h1>)を取得します。
- 段落(<p>)のテキストを一覧表示します。
- ページ内のリンク(<a>)を一覧表示します。
"""
# Beautiful Soup でHTMLを解析します。
soup = BeautifulSoup(html, "html.parser")
# 1. ページタイトル(<h1>)を取得
h1_tag = soup.find("h1")
if h1_tag is not None:
print("ページタイトル:")
print(h1_tag.get_text(strip=True))
else:
print("ページタイトル(<h1>)は見つかりませんでした。")
# 2. 段落(<p>)のテキストを一覧表示
p_tags = soup.find_all("p")
print("\n本文(<p>)一覧:")
for i, p in enumerate(p_tags, start=1):
text = p.get_text(strip=True)
print(f"[{i}] {text}")
# 3. ページ内のリンク(<a>)を一覧表示
a_tags = soup.find_all("a")
print("\nリンク一覧:")
for i, a in enumerate(a_tags, start=1):
href = a.get("href") # href属性からリンク先URLを取得します。
text = a.get_text(strip=True)
print(f"[{i}] テキスト='{text}', URL='{href}'")
def main():
url = "https://httpbin.org/html"
html = fetch_html(url)
if html is not None:
extract_info(html)
else:
print("HTMLを取得できなかったため、情報抽出を中止します。")
if __name__ == "__main__":
main()
Pythonこのコードは、 「1ページ分の情報収集ツール」 の基本形になっています。
ステップ3:情報収集ツールとしての「流れ」を整える
ツールの入口と出口を意識する
情報収集ツールとして考えると、
- 入口:URLを指定する
- 中身:HTML取得 → 解析 → 情報抽出
- 出口:結果を表示する/保存する
という流れになります。
ここでは、入口と出口を少し整えて、 「ツールらしい形」にしてみます。
# day53_info_tool.py
import requests
from bs4 import BeautifulSoup
def fetch_html(url: str) -> str | None:
"""指定URLからHTMLを取得する関数です。"""
print(f"[GET] {url} にアクセスします。")
try:
response = requests.get(url, timeout=5)
except requests.exceptions.RequestException as e:
print("HTML取得中にエラーが発生しました:", e)
return None
if 200 <= response.status_code < 300:
return response.text
else:
print("HTMLの取得に失敗しました。ステータスコード:", response.status_code)
return None
def extract_info(html: str) -> dict:
"""
HTMLから情報を抽出して、辞書としてまとめて返す関数です。
- title: ページタイトル
- paragraphs: 段落テキストのリスト
- links: (テキスト, URL) のタプルのリスト
"""
soup = BeautifulSoup(html, "html.parser")
# ページタイトル
h1_tag = soup.find("h1")
title = h1_tag.get_text(strip=True) if h1_tag is not None else None
# 段落テキスト
paragraphs = [
p.get_text(strip=True)
for p in soup.find_all("p")
]
# リンク一覧
links = []
for a in soup.find_all("a"):
text = a.get_text(strip=True)
href = a.get("href")
links.append((text, href))
return {
"title": title,
"paragraphs": paragraphs,
"links": links,
}
def print_info(info: dict):
"""抽出した情報を見やすく表示する関数です。"""
print("=== 情報収集結果 ===")
# タイトル
title = info.get("title")
if title:
print("\n[タイトル]")
print(title)
else:
print("\n[タイトル]")
print("(見つかりませんでした)")
# 段落
paragraphs = info.get("paragraphs", [])
print("\n[本文]")
if paragraphs:
for i, text in enumerate(paragraphs, start=1):
print(f"[{i}] {text}")
else:
print("(本文が見つかりませんでした)")
# リンク
links = info.get("links", [])
print("\n[リンク]")
if links:
for i, (text, href) in enumerate(links, start=1):
print(f"[{i}] テキスト='{text}', URL='{href}'")
else:
print("(リンクが見つかりませんでした)")
def main():
# 実際に使うときは、ここに「情報収集したいURL」を指定します。
url = "https://httpbin.org/html"
html = fetch_html(url)
if html is None:
print("HTMLを取得できなかったため、終了します。")
return
info = extract_info(html)
print_info(info)
if __name__ == "__main__":
main()
Pythonこの形になると、
- URLを変えるだけで、別のページの情報収集ができる
- 抽出した情報が辞書にまとまっているので、後でファイル保存などに発展させやすい
という「ツールらしさ」が出てきます。
ステップ4:マナーをコードの外側で意識する
ここまでのコードは「技術的にできること」を示していますが、 実際に運用するときには、次のような習慣をセットで持つことが大切です。
- 利用規約を読む
- 「自動取得」「スクレイピング」に関する記載がないか確認する
- robots.txtを確認する
- 禁止されているパスにはアクセスしない
- アクセス頻度を抑える
time.sleep()などで間隔を空ける
- 認証が必要なページには勝手にアクセスしない
- ログインが必要なページは、特に慎重に扱う
情報収集ツールは、 「技術的にできること」と「倫理的にやっていいこと」の両方を考えながら育てていくものです。
Day 53ミニテンプレート:情報収集ツールの基本形
最後に、Day 53の内容をコンパクトにまとめた 「情報収集ツール」テンプレート を載せておきます。
# day53_info_collect_tool_template.py
import time
import requests
from bs4 import BeautifulSoup
def fetch_html(url: str) -> str | None:
"""
指定URLからHTMLを取得する関数です。
- 公開情報を対象にします。
- タイムアウトと簡単なエラー処理を行います。
"""
print(f"[GET] {url} にアクセスします。")
try:
response = requests.get(url, timeout=5)
except requests.exceptions.RequestException as e:
print("HTML取得中にエラーが発生しました:", e)
return None
if 200 <= response.status_code < 300:
return response.text
else:
print("HTMLの取得に失敗しました。ステータスコード:", response.status_code)
return None
def extract_info(html: str) -> dict:
"""
HTMLから基本的な情報を抽出します。
- タイトル(<h1>)
- 段落(<p>)
- リンク(<a>)
"""
soup = BeautifulSoup(html, "html.parser")
# タイトル
h1_tag = soup.find("h1")
title = h1_tag.get_text(strip=True) if h1_tag is not None else None
# 段落
paragraphs = [
p.get_text(strip=True)
for p in soup.find_all("p")
]
# リンク
links = []
for a in soup.find_all("a"):
text = a.get_text(strip=True)
href = a.get("href")
links.append((text, href))
return {
"title": title,
"paragraphs": paragraphs,
"links": links,
}
def print_info(info: dict):
"""抽出した情報を見やすく表示します。"""
print("=== 情報収集結果 ===")
title = info.get("title")
print("\n[タイトル]")
print(title if title else "(見つかりませんでした)")
print("\n[本文]")
paragraphs = info.get("paragraphs", [])
if paragraphs:
for i, text in enumerate(paragraphs, start=1):
print(f"[{i}] {text}")
else:
print("(本文が見つかりませんでした)")
print("\n[リンク]")
links = info.get("links", [])
if links:
for i, (text, href) in enumerate(links, start=1):
print(f"[{i}] テキスト='{text}', URL='{href}'")
else:
print("(リンクが見つかりませんでした)")
def main():
# 実際に使うときは、ここに「情報収集したいURL」を指定します。
url = "https://httpbin.org/html"
# ※実運用では、この前に利用規約・robots.txtの確認を行う習慣を持つことが大切です。
html = fetch_html(url)
if html is None:
print("HTMLを取得できなかったため、終了します。")
return
info = extract_info(html)
print_info(info)
# アクセス間隔を空ける例(複数ページを巡回する場合)
time.sleep(1.0)
if __name__ == "__main__":
main()
PythonDay 53のまとめ
Day 53では、Webデータ取得と情報収集ツールの制作を通して、
- 公開情報を対象に、WebページからHTMLを取得する基本パターン
- Beautiful SoupでHTMLを解析し、タイトル・本文・リンクなどを抽出する流れ
- 抽出した情報を辞書にまとめて、ツールとして扱いやすくする考え方
- 利用規約・robots.txt・アクセス制限を確認する習慣の重要性
- 「技術的にできること」と「倫理的にやっていいこと」をセットで考える姿勢
を整理しました。
この土台があると、
- ニュースサイトから見出しだけを集める
- 公開されている統計ページから数値をまとめる
- 社内の公開レポートから必要な情報だけを抽出する
といった「情報収集ツール」を、 安全かつ丁寧な形で育てていくことができるようになります。
