気象衛星『ひまわり』の画像をDiscordに送信する

DiscordはDAO (Distributed Autonomous Organization – 分散型自立組織)の運営でコミュニティー活動を活発にするためによく使われるツールです。このDiscordはボットを開発して連携させることによって、メンバー同士の会話以外のサービスを容易に統合できるのという特徴を持っており、モノづくり塾では塾内のサーバーで動いている生成AIボット、Raspberry Pi NOAAを使った気象衛星から受信した画像の共有ボットを運用しています。これらのソースコードは塾内で共有して、塾生がソースコードを読んで勉強できるようにしています。

気象衛星の画像をRaspberry PiとSDRを使って受信するには、過去の投稿でも紹介したように、特殊なアンテナを作る必要がありますが、例えば気象衛星ひまわりの最新画像を取得するだけなら、気象画像を公開しているWebサイトから画像を取得するだけで済むので特殊な装置が必要ありません。非常に手軽に実現できる機能です。

今回は気象衛星ひまわりの最新画像を定期的に習得してDiscordに送信するプログラムを紹介します。

概要

2時間おきに最新のひまわり画像をダウンロードしてDiscordに送信する。

前提条件

  • あらかじめDiscordの特定のチャンネルでWebHookを生成し、そのURLを控えておく
  • 常時起動しているPCがある(サーバーのレンタル等は必要ありません)

プログラム

import requests
from bs4 import BeautifulSoup
import time
import os

# JMAのひまわり画像ページURL(例:最新の画像を取得)
JMA_URL = "https://tenki.jp/satellite/japan-near/"

DISCORD_WEBHOOK_URL = "事前に生成したDiscordチャンネルのWebHook URL"

# 保存先ディレクトリ
SAVE_DIR = "./himawari_images"
os.makedirs(SAVE_DIR, exist_ok=True)

def get_latest_image_url():
    try:
        # JMAのページを取得
        response = requests.get(JMA_URL, verify=False)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, "html.parser")

        # 画像URLを検索(例:HTML内のimgタグのsrc属性)
        # 実際のHTML構造に合わせて調整が必要です
        image_url = None
        elems = soup.find_all("img")
        for img in elems:
            if img.get("id") == "satellite-image":
                image_url = img["src"]
                break

        if image_url:
            # 相対パスを絶対URLに変換
            if image_url.startswith("//"):
                image_url = "https:" + image_url
            return image_url
        else:
            print("画像URLを取得できませんでした。")
            return None
    except Exception as e:
        print(f"エラー: {e}")
        return None

def download_image(url, filename):
    try:
        response = requests.get(url)
        response.raise_for_status()
        with open(filename, "wb") as f:
            f.write(response.content)
        print(f"画像を保存しました: {filename}")
        return filename
    except Exception as e:
        print(f"画像ダウンロードエラー: {e}")
        return

def send_to_discord(image_path, message="Himawari 画像"):
    try:
        with open(image_path, "rb") as f:
            files = {"file": f}
            data = {"content": message}
            response = requests.post(DISCORD_WEBHOOK_URL, data=data, files=files)
            response.raise_for_status()
            print("Discordに画像を送信しました。")
    except Exception as e:
        print(f"Discord送信エラー: {e}")

def main():
    while True:
        image_url = get_latest_image_url()
        if image_url:
            # 現在日時をファイル名に含める
            timestamp = time.strftime("%Y%m%d_%H%M%S")
            filename = os.path.join(SAVE_DIR, f"himawari_{timestamp}.jpg")
            download_file = download_image(image_url, filename)
            if download_file:
                send_to_discord(download_file, "最新のひまわりの画像です!")
        else:
            print("画像取得に失敗しました。")
        # 2時間ごとに実行(適宜調整)
        time.sleep(7200)

if __name__ == "__main__":
    main()

実行

私の場合は、次のようにVenvを使って仮想環境を作っています。

python3 -m venv venv #仮想環境の作成
. venv/bin/activate #仮想環境を有効化

仮想環境を作成・有効化したら、次のコマンドで必要なPythonライブラリーをインストールします。

pip install requests bs4

PCからログアウトしてもプログラムが実行され続けるように次のコマンドでプログラムを起動します。

nohup python3 main.py &

Discordに送信された画像です。

自分が作ったプログラムからDiscordにデータを送信するのは容易です。簡単なプログラムなのでプログラミング初学者の学習テーマにしても良いし、アイデア次第で楽しいサービスをコミュニティー運営に導入することもできます。

「気象衛星『ひまわり』の画像をDiscordに送信する」への1件のフィードバック

コメントする