PythonでWebサイトの更新を検出しDiscord通知【ChatGPT実践2】

PythonとWebスクレイピング、そしてDiscordのWebhook機能を組み合わせることで、Webページを定期的に監視し、自動で通知を受け取る仕組みを構築できます。
ここでは、賃貸の物件ページに対応した実装を紹介しますが、構造が分かれば他のサイトにも応用できます。

なお、Webスクレイピングは取得サイトのサーバー負荷を高めたり、著作権侵害のおそれがあることから規約によりスクレイピングを禁じているサイトが増えてきています。必ず対象サイトの規約を確認してください。

背景と目的

例えば定期的に更新がないか見に行くページがあるとして、それを「更新があったときだけ通知する」ような仕組みがあれば楽だなと思い作ってみることにしました。
この仕組み自体は珍しいものでもないですが、今回はAIにコーディングをすべて任せてみました。
今回はとある賃貸サイトの物件ページを見に行き、入居状況に更新があったら知らせるスクリプトを作りました。

使用ツールなど

今回の作業で使用したものは以下になります。

  • ChatGPT o3-mini-high
  • PythonとPythonの以下モジュール
    • request:Webページを取得
    • BeautifulSoup:HTMLデータの解析
    • time:時間データ取得
  • Discord

スクリプトの概要と機能

スクリプトは、URLリストに登録された物件ページを定期的に巡回し、ページ内の「現況」や「入居可」などの項目が変化したときにだけ通知を送るようになっています。
初回実行時はすべての物件の現況情報を通知し、それ以降は変更があった物件だけ通知されます。
また、取得間隔(例:1時間ごと)や通知に含める内容(URL、更新日、通知時刻など)も定数で管理できるため、柔軟な運用が可能です。

プロンプトの入力

まず、以下のようにやりたいことと実現方法を聞いてみました。いくつか選択肢を提示されましたが、最終的にDiscord Webhookが無料でわかりやすそうだったのでサンプルコードを書いてもらいました。

ある賃貸紹介サイトの物件情報が更新されたときに通知が来るようにしたいです。ChatGPTでリリースされている機能でこれを実装できますか?また、それ以外に方法があったら教えて下さい。

書いてもらったコードがこちら。

import requests
from bs4 import BeautifulSoup
import time

# Discord Webhook URL(コピーしてきたURLを貼り付け)
DISCORD_WEBHOOK_URL = "YOUR_DISCORD_WEBHOOK_URL"

# Discordに通知を送る関数
def send_discord_message(message):
    data = {
        "content": message  # メッセージ本文
    }
    response = requests.post(DISCORD_WEBHOOK_URL, json=data)
    if response.status_code == 204:
        print("Discordに通知を送信しました。")
    else:
        print(f"通知失敗: {response.status_code} {response.text}")

# 物件情報を取得する関数
def get_property_info(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    # サイトに合わせて物件情報を抽出(例: タイトルを取得)
    title = soup.find('title').text  # タイトルタグから物件名を取得
    return title

# メイン処理
PROPERTY_URL = "https://example.com/property"  # 監視したいURLに置き換える
previous_info = ""

while True:
    try:
        current_info = get_property_info(PROPERTY_URL)
        if current_info != previous_info:
            message = f"🏡 新着物件情報が更新されました!\n**{current_info}**\n{PROPERTY_URL}"
            send_discord_message(message)
            previous_info = current_info
        else:
            print("更新なし")
        time.sleep(300)  # 5分ごとにチェック
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        time.sleep(300)

なお、今回はBeautifulsoupが必要なのでインストールしておきます。

pip install requests beautifulsoup4

ここから、自分のイメージに近づけるようプロンプトを入力していきます。プロンプト→出力を何回か繰り返しました。

複数の物件ページを対象とし、更新があった物件とわかるようなメッセージを送信するようにできますか?

通知内容ですが、URLと情報更新日も入れてほしいです。

情報の取得間隔ですが、同じ構文が複数見られるので、あらかじめどこかで定義しておき、修正を容易にしたいです。 time.sleep(3600)

最終的には以下のようになりました。

import requests
from bs4 import BeautifulSoup
import time
import datetime

# Discord Webhook URL(自分のURLに置き換えてください)
DISCORD_WEBHOOK_URL = "YOUR_DISCORD_WEBHOOK_URL"

# 情報取得間隔(秒)← 例:1時間ごとに監視
SLEEP_INTERVAL = 3600

# 監視対象のSUUMO物件URLリスト
PROPERTY_URLS = [
    "https://suumo.jp/chintai/<物件ID>/",
    "https://suumo.jp/chintai/<物件ID>/",
    "https://suumo.jp/chintai/<物件ID>/"
]

# 現在のステータスを記録する辞書
previous_statuses = {}

# HTTPリクエスト用ヘッダー(403回避対策)
HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/111.0.0.0 Safari/537.36"
    ),
    "Referer": "https://suumo.jp/",
    "Accept-Language": "ja,en-US;q=0.9,en;q=0.8"
}

def send_discord_message(message: str):
    """Discord Webhookにメッセージを送信"""
    data = {"content": message}
    response = requests.post(DISCORD_WEBHOOK_URL, json=data)
    if response.status_code == 204:
        print("通知送信済み")
    else:
        print(f"通知失敗: {response.status_code} {response.text}")

def get_suumo_property_info(url: str):
    """SUUMO物件ページから物件名・入居状況・更新日を取得"""
    try:
        response = requests.get(url, headers=HEADERS)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, "html.parser")

        # 物件名
        title_tag = soup.find("h1")
        property_name = title_tag.text.strip() if title_tag else "物件名不明"

        # 入居状況と更新日
        current_status = "入居状況不明"
        update_date = "更新日不明"

        data_table = soup.find("table", class_="data_table table_gaiyou")
        if data_table:
            rows = data_table.find_all("tr")
            for row in rows:
                th = row.find("th")
                td = row.find("td")
                if not th or not td:
                    continue
                th_text = th.get_text(strip=True)
                td_text = td.get_text(strip=True)
                if "入居" in th_text:
                    current_status = td_text
                elif any(keyword in th_text for keyword in ["更新", "公開", "掲載"]):
                    update_date = td_text

        return property_name, current_status, update_date

    except Exception as e:
        print(f"取得失敗: {url} エラー: {e}")
        return "物件名不明", "取得失敗", "更新日不明"

# メインループ
while True:
    try:
        for url in PROPERTY_URLS:
            property_name, current_status, update_date = get_suumo_property_info(url)

            # 初回または更新時のみ通知
            if url not in previous_statuses or current_status != previous_statuses[url]:
                now_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                message = (
                    f"🏡 【{property_name}】ステータスが更新されました!\n"
                    f"現況: **{current_status}**\n"
                    f"更新日: {update_date}\n"
                    f"URL: {url}\n"
                    f"(通知時刻: {now_str})"
                )
                send_discord_message(message)
                previous_statuses[url] = current_status
            else:
                print(f"更新なし: {property_name}(現況: {current_status})")

        time.sleep(SLEEP_INTERVAL)

    except Exception as e:
        print(f"ループエラー: {e}")
        time.sleep(SLEEP_INTERVAL)

コード内のDISCORD_WEBHOOK_URLとPROPERTY_URLSを任意の値に修正してスクリプトを実行すれば動きます。

python multi_property_notify.py

補足:Discord側の準備(PC)

物件情報の通知を受け取るには、Discordのウェブフック機能を使います。簡単なやり方を紹介します。
アプリ版だとウェブフック作成ができないようなのでPCブラウザで操作しています。(バージョンによってはできるようになっているかもしれません)

Discordアカウント作成

Discordアカウントを持っていない場合は、アカウントを作成します。画面に従って入力すればすぐ作れます。

サーバーとチャンネルの作成

ログイン後、PCブラウザで見ている場合は画面左側に四角アイコンが表示されています。このアイコンの中から、プラスマーク(+)をクリックしサーバー作成を進めます。
「オリジナルの作成」→「自分と友達のため」の順にクリックし、サーバー名を指定して「新規作成」します。

作成されたチャンネルが選択された状態で、左ペインの「テキストチャンネル」右のプラス部分(+)をクリックし、チャンネルを作成します。このチャンネルに後述のウェブフックを紐付けます。
「テキスト」を選択肢、チャンネル名を指定して作成します。

サーバーが選択された状態で、サーバー名右の歯車アイコン>サーバー設定の順にクリックします。

「連携サービス」をクリックするとウェブフック機能があります。ウェブフックをクリックします。

新しいウェブフックをクリック。

新しいウェブフックが作成されます。デフォルト設定になっているウェブフックを編集していきます。
Bot名を入力し、チャンネルを先ほど作成したチャンネルに設定します。
ここで作成されたウェブフックのURLをコピーし、コードに貼り付けたら完了です。

実行方法と運用上の注意点

スクリプトはPythonで実行するだけでOKです。処理後にtime.sleep()で指定した時間分だけ休止し、再び処理を繰り返します。
ずっと動かし続けるため、実行中はプロセスを止めないようにする必要があります。終了したい場合は、Ctrl+Cで手動停止できます。
実行中のメモリ使用量は数MB程度と非常に軽く、PCのリソースにほとんど影響を与えません。バックグラウンドでの運用にも向いています。

まとめ

Pythonで物件情報を定期的にチェックし、更新があったらDiscordで受け取る仕組みを一度作っておけば、日々の手間を大きく減らせます。
個人でも気軽に始められる自動監視の第一歩として活用してみてください。

タイトルとURLをコピーしました