メインコンテンツへスキップ
見出し画像

Pythonでニュース収集を自動化。「AI社員」をもう少し働かせてみます。

    前回の記事では、

    RSS+Feedly+ChatGPT

    を使って、毎朝のセキュリティ情報を整理してくれる「AI社員」を作りました。

    プログラミングは使っていません。

    Feedlyにニュースを集めて、

    人間がその情報をChatGPTに渡して、

    「今日、自分の会社が確認した方がいい情報は何?」

    と整理してもらう仕組みです。

    これだけでも、かなり便利です。

    ただし、毎日使っていると一つ面倒な作業が残ります。

    Feedlyを開いて、ニュースを確認して、ChatGPTに渡す。

    今回は、このうちニュース収集の部分をPythonに任せます。

    しかも今回は、考え方だけではありません。

    実際に動くPythonのプログラムを作ります。

    やることはシンプルです。

    JPCERT/CCのRSSから、過去24時間に公開された情報だけを取得して、一つのテキストファイルにまとめる。

    あとは、そのファイルをChatGPTに渡します。

    まだAI APIは使いません。

    前回より、「AI社員」にもう少し働いてもらいます。


    今回、自動化するところ

    前回はこうでした。

    JPCERT/CC
    ↓
    RSS
    ↓
    Feedly
    ↓
    人間がニュースを確認
    ↓
    ChatGPTへ渡す
    ↓
    AIが分析・整理

    今回はこうします。

    JPCERT/CC
    ↓
    RSS
    ↓
    Pythonが過去24時間の情報を取得
    ↓
    テキストファイルを自動生成
    ↓
    人間がChatGPTへ渡す
    ↓
    AIが分析・整理

    つまり、

    Feedlyでニュースを確認して、ChatGPTに渡せる形にまとめる

    という作業をPythonに置き換えます。

    今回もJPCERT/CCを使います

    前回と比較しやすいように、今回も情報源はJPCERT/CCです。

    JPCERT/CCでは、

    注意喚起・緊急報告、

    Weekly Report、

    JVNで公開された脆弱性情報、

    JPCERT/CCからのお知らせ、

    などをRSSで配信しています。

    前回は、このRSSをFeedlyに登録しました。

    今回はPythonから直接取得します。

    使うのは、JPCERT/CCが公開している統合版RSSです。

    JPCERT/CCのRSS配信ページはこちらです。

    https://www.jpcert.or.jp/rss/

    RSSのURLについては、上記の公式ページに掲載されている**「統合版 JPCERT/CC RSS」**を使用します。

    今回作るプログラム

    今回のPythonがやることは4つだけです。

    ① JPCERT/CCのRSSを取得する

    ② 公開日時を確認する

    ③ 過去24時間に公開された情報だけを残す

    ④ ChatGPTに渡すテキストファイルを作る

    難しいことはしません。

    完成すると、

    security_news_20260829.txt

    のようなファイルが自動的に作られます。

    中には、過去24時間に公開されたセキュリティ情報だけが入っています。

    まずfeedparserをインストールします

    今回はPythonでRSSを扱うために、

    feedparser

    というライブラリを使います。

    WindowsならコマンドプロンプトやPowerShell。

    Macならターミナルを開きます。

    そして、

    pip install feedparser

    を実行します。

    環境によっては、

    python -m pip install feedparser

    または、

    python3 -m pip install feedparser

    でも構いません。

    これで準備完了です。

    完成版のPythonです

    今回は断片的なコードではなく、そのまま実行できる形にします。

    例えば、

    security_news.py

    という名前で以下を保存します。

    import feedparser
    from datetime import datetime, timedelta, timezone
    from pathlib import Path
    from calendar import timegm
    import re
    
    # --------------------------------------------------
    # 設定
    # --------------------------------------------------
    
    RSS_URL = "https://www.jpcert.or.jp/rss/jpcert-all.rdf"
    
    OUTPUT_DIR = Path(__file__).resolve().parent
    
    # 過去何時間の記事を取得するか
    HOURS = 24
    
    JST = timezone(timedelta(hours=9))
    
    
    # --------------------------------------------------
    # HTMLタグを簡単に除去
    # --------------------------------------------------
    
    def remove_html_tags(text):
        if not text:
            return ""
    
        return re.sub(r"<[^>]+>", "", text).strip()
    
    
    # --------------------------------------------------
    # RSSを取得
    # --------------------------------------------------
    
    feed = feedparser.parse(RSS_URL)
    
    if feed.bozo:
        print("RSSの解析時に警告が発生しました。")
        print(feed.bozo_exception)
    
    print(f"RSS内の記事数:{len(feed.entries)}件")
    
    
    # --------------------------------------------------
    # 取得対象期間
    # --------------------------------------------------
    
    now = datetime.now(timezone.utc)
    border_time = now - timedelta(hours=HOURS)
    
    articles = []
    
    
    # --------------------------------------------------
    # 過去24時間の記事だけ抽出
    # --------------------------------------------------
    
    for entry in feed.entries:
    
        # RSSによって日付フィールドが異なるため、
        # published_parsed → updated_parsed の順に確認
        date_parsed = None
    
        if entry.get("published_parsed"):
            date_parsed = entry.published_parsed
    
        elif entry.get("updated_parsed"):
            date_parsed = entry.updated_parsed
    
        # 日付が取得できない記事は対象外
        if not date_parsed:
            continue
    
        # feedparser の struct_time はUTCとして扱う
        published = datetime.fromtimestamp(
            timegm(date_parsed),
            tz=timezone.utc
        )
    
        # 過去24時間より古い記事は除外
        if published < border_time:
            continue
    
        title = entry.get("title", "タイトルなし")
        link = entry.get("link", "")
    
        summary = remove_html_tags(
            entry.get("summary", "")
        )
    
        articles.append(
            {
                "title": title,
                "link": link,
                "summary": summary,
                "published": published,
            }
        )
    
    
    # --------------------------------------------------
    # 新しい記事から並べる
    # --------------------------------------------------
    
    articles.sort(
        key=lambda x: x["published"],
        reverse=True
    )
    
    
    # --------------------------------------------------
    # ファイル名を作成
    # --------------------------------------------------
    
    today = datetime.now(JST).strftime("%Y%m%d")
    
    output_file = (
        OUTPUT_DIR
        / f"security_news_{today}.txt"
    )
    
    
    # --------------------------------------------------
    # テキストファイルへ保存
    # --------------------------------------------------
    
    with output_file.open(
        "w",
        encoding="utf-8"
    ) as f:
    
        f.write(
            "JPCERT/CC 過去24時間のセキュリティ情報\n"
        )
    
        f.write("=" * 50 + "\n\n")
    
        f.write(
            "取得日時:"
            + datetime.now(JST).strftime(
                "%Y-%m-%d %H:%M:%S"
            )
            + "\n"
        )
    
        f.write(
            f"取得件数:{len(articles)}件\n\n"
        )
    
        if not articles:
    
            f.write(
                "過去24時間に公開された情報は"
                "ありませんでした。\n"
            )
    
        else:
    
            for number, article in enumerate(
                articles,
                start=1
            ):
    
                published_jst = (
                    article["published"]
                    .astimezone(JST)
                )
    
                f.write(f"【{number}】\n")
    
                f.write(
                    f"タイトル:{article['title']}\n"
                )
    
                f.write(
                    "公開日時:"
                    + published_jst.strftime(
                        "%Y-%m-%d %H:%M:%S"
                    )
                    + "\n"
                )
    
                f.write(
                    f"URL:{article['link']}\n"
                )
    
                if article["summary"]:
                    f.write(
                        f"概要:{article['summary']}\n"
                    )
    
                f.write("\n")
                f.write("-" * 50)
                f.write("\n\n")
    
    
    # --------------------------------------------------
    # 完了
    # --------------------------------------------------
    
    print(
        f"過去{HOURS}時間の記事:"
        f"{len(articles)}件"
    )
    
    print(
        f"出力ファイル:{output_file}"
    )

    これが今回使う完成版です。

    プログラムを実行します

    保存したら、ターミナルやコマンドプロンプトから、

    Windowsなら、

    python security_news.py

    MacなどでPython 3を`python3`として利用している場合は、

    python3 security_news.py

    を実行します。

    正常に処理されると、

    3件の記事を取得しました。
    出力ファイル:.../security_news_20260829.txt

    のように表示されます。

    同じフォルダを見ると、

    security_news_20260829.txt

    が作られています。

    テキストファイルを開いてみます

    中身は、このような形になります。

    JPCERT/CC 過去24時間のセキュリティ情報
    ==================================================
    
    取得日時:2026-08-29 06:00:03
    取得件数:3件
    
    【1】
    タイトル:○○に関する注意喚起
    公開日時:2026-08-29 03:00:00
    URL:https://...
    
    概要:○○についての情報が公開されました。
    
    --------------------------------------------------
    
    【2】
    タイトル:○○製品の脆弱性について
    公開日時:2026-08-27 18:30:00
    URL:https://...
    
    概要:○○...
    
    --------------------------------------------------

    これで、

    ニュースを探す

    公開日時を確認する

    24時間以内か判断する

    ChatGPTへ渡せるようにまとめる

    という作業をPythonがやってくれます。

    あとは、このファイルをChatGPTに渡します

    ここからは簡単です。

    作成された、

    security_news_20260829.txt

    をChatGPTに添付します。

    そして、前回作ったプロンプトを使います。

    ChatGPTに入力するプロンプト

    あなたは中小企業の情報セキュリティ担当者です。

    添付したファイルには、過去24時間に収集したサイバーセキュリティ関連情報が記載されています。

    従業員20名程度の一般的な中小企業を想定して、今日確認すべき情報を整理してください。

    以下の基準で判断してください。

    1. 各情報の重要度を★★★★★の5段階で評価する

    2. 専門知識がない人にも分かるように説明する

    3. Windows、Microsoft 365、Google Chrome、WordPressなど、一般的な中小企業でも利用する可能性が高い製品を優先する

    4. 一般的な中小企業への影響が小さい専門製品の情報は重要度を下げる

    5. 各ニュースを200文字以内で要約する

    6. 中小企業にどのような影響があるのか説明する

    7. 今日確認した方がよいことがあれば具体的に記載する

    8. 重要度の高い順番に並べる

    出力形式は以下にしてください。

    【ニュースタイトル】

    重要度:★★★★★

    概要:
    ○○

    中小企業への影響:
    ○○

    今日確認すること:
    ○○

    特に対応が必要な情報がない場合は、無理に★★★★★を付けないでください。

    これで、

    Pythonがニュース収集担当。

    ChatGPTがニュース分析担当。

    という役割分担ができました。

    毎朝Pythonを実行するのも面倒です

    さて。

    ここまで作ると、もう一つ気になることが出てきます。

    毎朝、

    python security_news.py

    と入力するのも面倒です。

    だったら、これも自動化してしまえばいい。

    Pythonは決められた時間に自動実行できます。

    Windowsならタスクスケジューラ

    Windowsには、

    タスクスケジューラ

    という機能があります。

    例えば、

    毎朝6時にsecurity_news.pyを実行する

    という設定ができます。

    これなら朝パソコンを使い始めた時点で、

    security_news_20260829.txt

    がすでに完成しています。

    Macならlaunchd

    Macなら、

    launchd

    を使って定期実行できます。

    こちらも、

    毎朝6時にsecurity_news.pyを実行する

    といった設定が可能です。

    今回はニュース収集プログラムそのものがテーマなので、タスクスケジューラやlaunchdの設定方法までは掘り下げません。

    ただ、

    Pythonを書いたあと、人間が毎日実行する必要はない

    ということは覚えておくと便利です。

    一度作ったプログラムを、

    決められた時間に勝手に働かせる。

    これも業務自動化では非常によく使う考え方です。

    朝起きたら、ニュースファイルが完成しています

    ここまで設定すると、

    毎朝6時。

    人間がまだ仕事を始める前にPythonが動きます。

    JPCERT/CCのRSSを確認する。

    過去24時間の記事を抽出する。

    テキストファイルを作る。

    ここまで自動です。

    朝、人間がやるのは、

    出来上がったファイルをChatGPTに渡すだけ。

    前回より、かなり楽になりました。

    それでもAI APIを使わない理由

    ここまで来ると、

    「ChatGPTに渡すところもPythonでやればいいのでは?」

    と思います。

    その通りです。

    できます。

    でも今回は、あえてやりません。

    AI APIを使えば、

    PythonからAIへニュースを送る。

    AIが分析する。

    結果を保存する。

    というところまで自動化できます。

    ただし、

    APIキーの管理、

    API料金、

    エラー処理、

    入力データ量、

    出力データの管理、

    など、考えることも増えます。

    まずは、

    Pythonで情報収集だけ自動化する。

    そして普段使っているChatGPTにファイルを渡す。

    これならAI APIの利用料金を別途発生させずに試せます。

    自動化は、一気にやらなくていい

    前回は、

    RSS+Feedly+人間+ChatGPT

    でした。

    今回は、

    Python+人間+ChatGPT

    です。

    そしてPythonをタスクスケジューラやlaunchdで動かせば、

    Pythonが毎朝勝手に情報を集める+人間+ChatGPT

    になります。

    人間の仕事が、また一つ減りました。

    私は、こういう自動化の進め方が好きです。

    最初から、

    「全部自動化しよう」

    と考えない。

    まず動かす。

    使ってみる。

    面倒なところを見つける。

    そこを一つ自動化する。

    また使う。

    そして次を自動化する。

    この繰り返しです。

    「AI社員」が、また少し成長しました

    最初のAI社員は、

    人間がニュースを探していました。

    前回はFeedlyに集めてもらいました。

    今回はPythonが、

    毎朝、自分でRSSを確認して、過去24時間の情報をファイルにまとめる

    ところまで担当します。

    しかもタスクスケジューラやlaunchdを使えば、

    人間がPythonを起動する必要すらありません。

    かなり社員らしくなってきました。

    ただし、一つだけ仕事が残っています。

    出来上がったファイルをChatGPTに渡すこと。

    ここだけは、まだ人間がやっています。

    次回、最後の手作業をなくします

    次は、この作業も自動化します。

    PythonからAI APIへ直接情報を送る。

    AIがニュースを読む。

    重要度を判断する。

    内容を要約する。

    自社への影響を分析する。

    そして結果を保存する。

    ここまで自動化できれば、

    朝、人間がやることはありません。

    仕事を始めた時点で、

    「本日確認すべき業界ニュース」

    が完成しています。

    最初の記事で考えた、

    毎朝、業界ニュースをまとめてくれる「AI社員」

    の完成です。

    次回は、いよいよフルスペック版を作ってみます。

     
     
    Web制作・システム開発歴20年以上。AI・Python・RPAを実際の仕事で使いながら、業務自動化やWeb集客について発信しています。うまくいったことだけでなく、失敗したことや現場で感じたことも書いています。

    あなたへのおすすめ