RSSフィードからPythonでニュースを取得

Python

RSSフィードとは?

RSSフィード(Really Simple Syndication / RDF Site Summary)は、ウェブサイトの更新情報を配信するためのフォーマットです
ニュースサイトやブログが新しい記事を公開すると、RSSフィードにその情報が自動的に追加されます

RSSフィードは「新聞の見出し一覧」のようなものです
ニュースサイトやブログの記事が更新されると、その見出しが RSSフィードに追加され、
ユーザーはリアルタイムで新着情報をチェックできます

RSSの特徴

  • RSSフィードは無料でリアルタイムニュースが取得できる
  • APIキー不要で簡単に使える
  • Pythonなどでスクレイピングせずにニュース収集ができる

RSSフィードの活用方法

  • ニュースの自動収集(Pythonで定期取得 → 企業ニュースの分析)
  • ブログの更新情報取得(新着記事を通知)
  • 株式ニュースのリアルタイム監視(日経新聞やロイターのRSS)

RSSフィードの仕組み

  • ニュースサイトやブログがRSSフィードを公開
    • yahoo ニュースのRSSのページはこちら
RSS一覧 - Yahoo!ニュース
ニュース配信記事のRSS情報一覧がご覧になれます。RSS購読にはRSSリーダーなど専用ツールが必要となります。第三者が提供するそれらのツールはYahoo!ニュースとは関係はありません。
  • RSSリーダーやプログラムが定期的にフィードを取得
    • ユーザーは RSSフィードを購読(登録)して、最新記事のリストを受け取る
  • 新しい記事があると、自動的に情報が更新される
    • APIを使わずに最新のニュース情報を取得できる

RSSフィードの中身

RSSフィードは XML形式(拡張マークアップ言語)で書かれています
Yahoo!ニュース(国内)のRSSフィードの一部 は以下のようになっています

<rss version="2.0">
  <channel>
    <title>Yahoo!ニュース - 国内</title>
    <link>https://news.yahoo.co.jp</link>
    <description>Yahoo!ニュースの国内カテゴリ</description>

    <item>
      <title>新型コロナの最新状況</title>
      <link>https://news.yahoo.co.jp/articles/123456</link>
      <pubDate>Mon, 12 Feb 2024 12:00:00 GMT</pubDate>
      <description>新型コロナウイルスに関する最新のニュースです。</description>
    </item>

    <item>
      <title>東京都の大雪警報</title>
      <link>https://news.yahoo.co.jp/articles/789012</link>
      <pubDate>Mon, 12 Feb 2024 14:30:00 GMT</pubDate>
      <description>東京都で大雪警報が発令されました。</description>
    </item>

  </channel>
</rss>

RSSとニュースAPIの違い

  • 取得方法
    • RSS:各サイトが提供するRSSを取得
    • API:API経由でニュース取得
  • リアルタイム性
    • RSS:ほぼリアルタイム
    • API:無料APIは遅延あり
  • 利用料金
    • RSS:無料
    • API:無料枠に制限あり
  • 商用利用
    • RSS:サイトの規約による
    • API:APIごとに制限あり

RSSフィードとスクレイピングの違い

RSSフィードとスクレイピング(Webスクレイピング)は、どちらも ウェブ上の情報を取得する手法 ですが、方法やメリット・デメリットが異なります

  • RSSフィード
    • サイトが公式に提供 しているデータなので、ルールに従えば合法的に使える
    • 取得できるデータは限られる(基本的に記事タイトル、URL、簡単な概要など)
    • 定期的に更新される ので リアルタイムでニュース収集に向いている
    • HTML構造の変化に影響を受けない(スクレイピングだと、サイトのレイアウト変更でコード修正が必要)
  • スクレイピング
    • サイトのHTMLを解析してデータを抽出(例えば全文取得などRSSではできないことが可能)
    • 自由度が高い(ニュース本文・画像・タグなど細かく取得できる)
    • サイトの規約違反になる可能性がある(APIがあるならAPIの利用を推奨)
    • サーバー負荷が高い(大量のリクエストを送るとブロックされることも)

🔹 短いニュース情報を手軽に取得するなら → RSSフィード(推奨)
🔹 記事の全文やカスタムデータを取得するなら → スクレイピング(ただし規約注意)


RSSフィードはサーバーにあまり負担をかけない

基本的に RSSフィードはサーバーに大きな負担をかけないものです
それでも取得の頻度や方法次第で、負荷が増えることもあるので注意が必要です

負担が少ない理由

  1. RSSはサイト運営者が公式に提供しているもの
    → すでにデータを 機械的に取得されることを前提 にしている
  2. HTML全体ではなく、最小限のデータだけ提供される
    → サイトのすべての画像やCSSを読み込まないので軽い
  3. APIのような制限がほぼない(ただしサイトによる)
    → Google News API などのAPIと違い、リクエスト制限なしで取得できる場合が多い

負担がかかるケース

あまりにも高頻度でアクセスしすぎるとサーバーに負荷がかかります
例えば、1分おきにRSSを取得 すると、サーバーに余計なリクエストが増えることになります

負荷を減らす工夫

  • 取得頻度を適切に設定する(10分~1時間ごと)
  • 変更があったときだけ取得する(HTTPヘッダーのIf-Modified-Sinceを利用)
  • キャッシュを利用して不要なリクエストを減らす

PythonでYahoo! Japan ビジネスニュースのRSSを取得するコード

Pythonの feedparser ライブラリを使えば簡単にRSSフィードを取得できます

環境

  • Windows 11
  • Python 3.12.2
  • feedparser 6.0.11
  • requests 2.32.3
  • python-dotenv 1.0.1

必要なライブラリをインストール

pip install feedparser requests python-dotenv

Yahoo! Japan ビジネスニュースのRSSを取得するPythonコード

まず、RSSの情報にどんなものが含まれているか、1件分だけ取得して中身を確認してみます

import feedparser

# Yahoo! Japan ビジネスニュースのRSSフィード
rss_url = "https://news.yahoo.co.jp/rss/categories/business.xml"
feed = feedparser.parse(rss_url)

# 最初のニュース記事のデータ構造を確認
if feed.entries:
    entry = feed.entries[0]  # 最初の記事を取得
    for key, value in entry.items():
        print(f"{key}: {value}")
else:
    print("RSSフィードに記事がありません。")

少しコードの解説をします

feed = feedparser.parse(rss_url)
feedparserを使ってRSSを解析してfeedという関数に代入します

if feed.entries:
feed.entries はリスト形式で、このリストの中には 各ニュース記事を表す辞書(dict) が入っています
Pythonでは 空のリストは False と評価されるため、RSSに1つ以上リストがあるなら True です


実行結果

1件分の以下のような情報が取得できました

title: TikTok猶予を延長も トランプ米大統領(共同通信)
title_detail: {'type': 'text/plain', 'language': None, 
               'base': 'https://news.yahoo.co.jp/rss/categories/business.xml',
               'value': 'TikTok猶予を延長も\u3000トランプ米大 統領(共同通信)'}
links: [{'rel': 'alternate', 'type': 'text/html',
         'href': 'https://news.yahoo.co.jp/articles/a1c1de13524a28ba2b731a2252da7d9cf90ff59f?source=rss'}]
link: https://news.yahoo.co.jp/articles/a1c1de13524a28ba2b731a2252da7d9cf90ff59f?source=rss
published: Thu, 13 Feb 2025 20:04:28 GMT
published_parsed: time.struct_time(tm_year=2025, tm_mon=2, tm_mday=13, tm_hour=20, tm_min=4, tm_sec=28, tm_wday=3, tm_yday=44, tm_isdst=0)
comments: https://news.yahoo.co.jp/articles/a1c1de13524a28ba2b731a2252da7d9cf90ff59f/comments
summary: 【ワシントン共同】ロイター通信によると、トランプ米大統領は13日の記者会見で、
           中国系動画投稿アプリ「TikTok(ティックトック)」の米国内でのサービス禁止を
           75日間 猶予した措置について、延長する可
summary_detail: {'type': 'text/html', 'language': None,
                 'base': 'https://news.yahoo.co.jp/rss/categories/business.xml',
                 'value': '【ワシントン共同】ロイター通信によると、トランプ米大統領は13日の記者会見で、
                 中国系動画投稿アプリ「TikTok(ティックトック)」の米国内でのサービス禁止を75日間猶予
                 した措置について、延長する可'}

実際にはここまでの情報は必要ないので少しコードを変えます


変更後のコード

import feedparser

# Yahoo! Japan ビジネスニュースのRSSフィード
rss_url = "https://news.yahoo.co.jp/rss/categories/business.xml"
feed = feedparser.parse(rss_url)

# ニュース記事を表示
for entry in feed.entries[:10]: # 最新10件のみ
    print(f"タイトル: {entry.title}")  
    print(f"リンク: {entry.link}")      
    print(f"要約: {entry.summary}")    
    print("-" * 50)
  • feedparser.parse(rss_url) → RSSフィードを取得
  • feed.entries → 記事リスト(entry.title や entry.link で情報取得)
  • [:10] → 最新10件を取得

LINE Message APIを使って送信する

取得したニュースをLINEで自分に送信したいと思います
LINE Message APIの使い方は以下の記事で紹介していますので参考にしてください

コードを以下のように変更します

import requests
import feedparser
import os
from dotenv import load_dotenv

# .envファイルを読み込む
load_dotenv()

# LINE Messaging APIの設定
LINE_ACCESS_TOKEN = os.getenv("LINE_ACCESS_TOKEN")  
LINE_API_URL = "https://api.line.me/v2/bot/message/broadcast"  # 一斉送信用URL

# Yahoo! Japan ビジネスニュースのRSSフィード
rss_url = "https://news.yahoo.co.jp/rss/categories/business.xml"
feed = feedparser.parse(rss_url)

# LINEに送信するメッセージを作成
messages = []

for entry in feed.entries[:5]:  # 最新5件のみ送信
    title = entry.title
    link = entry.link
    summary = entry.summary if "summary" in entry else "(要約なし)"
    
    # メッセージのフォーマット
    message_text = f"📢 {title}\n🔗 {link}\n📝 {summary}"
    
    # LINEのメッセージ形式(リスト)に追加
    messages.append({"type": "text", "text": message_text})

# LINE APIへリクエスト
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {LINE_ACCESS_TOKEN}"
}

payload = {"messages": messages}

response = requests.post(LINE_API_URL, json=payload, headers=headers)

# 結果を表示
print(response.status_code, response.json())

これでRSSで取得したニュースをLINEで送信することができました

LINEのmessage APIは一度に送れるメッセージが5件になっているので、たくさん件数を送りたい場合は一つのメッセージにたくさんの情報を入れるなど工夫をする必要があります

次回はこのRSSで取得したニュースから会社名を抽出して、株価の変動を見る機能を追加したいと思います

コメント