PythonでRSSのフィードのデータを取得してニュースとか天気を表示する電光掲示板をつくろう.


まえがき

ゴミ箱の中から真っ二つになったノートパソコンをみつけた。

二つに分離するというだけで、液晶も割れてないしなんだか勿体ない。そこでプラバンを駆使して以下のようなものを作った。

中々よくできている。

この作った一体型パソコン(?)を有効に活用すべく、任意のRSSからフィードを取得してニュースやら天気やら情報を表示する電光掲示板をPythonを用いて製作した。

こんな感じ。
本記事ではこのRSSのフィードを取得して表示するプログラムを紹介していく。

だれかのなにか創作物にお役に立てれば幸いです。

開発環境

本システムのプログラムにはPython3.9を使用しております。PythonであればWindowsであろうがLinuxであろうが、OS環境によらず安易に動作させることができるので採用しました。

使用したライブラリは以下のとおりです。

library
import tkinter
import feedparser
import threading
import time

from tkinter import font
from PIL import Image, ImageTk

ライブラリには特別環境に左右されて動作しなくなるものは用いてないため、現時点で確認したところではPythonのバージョンは3系以上であれば動作するようです。

ソースコード

はじめにRSSのフィードをPythonで取得した際の文字列を一時的に保存しておく場所を用意しておきます。

blank = []  # RSS取得後の一時保存場所
head = []   # title用
disc = []   # feed用

news = "http://feeds.bbci.co.uk/news/video_and_audio/uk/rss.xml"  # 任意のRSSリンク(ex.BBC-UK)

後に表示する際にタイトルやら内容やらを別々に表示したいので、ここでも保存場所を別々に用意しておきます。またRSSも変更や追加に備えてリンクをわかりやすく明記しておくと便利です。

次にRSSフィードを表示するウインドウの設定を行います。

window
def window():

    global canvas, top, caption, contents, item

    root = tkinter.Tk()
    root.title()

    root.geometry("1920x1080")  # ウインドウサイズ指定
    root.configure(background='white')
    root.attributes("-fullscreen", True)  # フルスクリーン化用

    fontx = font.Font(family='Arial', size=60, weight='bold')  # RSS最初の語句(引用元想定)フォント設定
    fonty = font.Font(family='Times', size=50, weight='bold')  # titleフォント設定
    fontz = font.Font(family='', size=70, weight='bold')  # feedフォント設定

    canvas = tkinter.Canvas(bg="white", width=1920, height=1080)
    canvas.place(x=0, y=0)

    img = Image.open('image.png')
    img = ImageTk.PhotoImage(img)

    item = canvas.create_image(0, 0, image=img, anchor=tkinter.NW)

    top = canvas.create_text(950, 200, width=1200, text="", font=fontz, fill='black', angle=0)  # fontxの位置設定
    caption = canvas.create_text(950, 500, width=1500, text="", font=fontx, fill='black', angle=0)  # fontyの位置設定
    contents = canvas.create_text(900, 800, width=1500, text="", font=fonty, fill='black', angle=0)  # fontzの位置設定

    root.mainloop()

ウインドウサイズは各々のモニタの解像度に合うサイズroot.geometry()を指定してください。

また、そのサイズ変更に伴ってそれぞれのフォントサイズ(この場合font.Font(size=A)Aの値)の変更および、フォントの位置(この場合はcanvas.create_text(X, Y, width=Z)XYZの値)を変更する必要があります。この値は好みで目視確認しつつ調整してください。

またキャンバスを生成するのに裏地が必要となるので、適当なウインドウサイズでimge.pmgを用意しておいてください。

次にRSSのフィードを取得していきます。

reader
def reader(link):

    d = feedparser.parse(link)

    blank.clear()
    blank.append(d['feed']['title'])

    for i in d.entries:
        head.append(i.title)
        disc.append(i.description)

はじめにfeedparserを用いてRSSのフィードを取得しblankに押し込みます。その後、それぞれの場所にtitlefeedを追加していくわけですが、ここで何故わざわざblankなるモノを用意して一時的に全てのフィードを挿入しているかというと、先のfontxにてこのRSSの出典元(はじめのtitle)を表示したいのですが以下のfor文ではその部分がスルーされてしまい、上手に表示することができませんでした。

もう少し頭の良い方法があるかと思いますが、とりあえず目標は達成したのでOKとします。

repeat
def repeat():

    while True:

        img = Image.open('image.png')  # タイトル画像
        img = ImageTk.PhotoImage(img)

        n_img = Image.open('image.png')  # ニュースフィード背景画像
        n_img = ImageTk.PhotoImage(n_img)

        canvas.itemconfig(item, image=img)

        time.sleep(3)  # タイトル画像切り替え時間

        reader(news)

        for i in range(len(head)):
            canvas.itemconfig(item, image=n_img)
            canvas.itemconfig(top, text=blank[0])
            canvas.itemconfig(caption, text=head[i])
            canvas.itemconfig(contents, text=disc[i])

            time.sleep(10)  # ニュースフィードの間隔時間

        head.clear()
        head.append("")
        canvas.itemconfig(top, text=head[0])
        canvas.itemconfig(caption, text=head[0])

        disc.clear()
        disc.append("")
        canvas.itemconfig(contents, text=disc[0])

最後に任意時間枚にフィードと背景画像を切り替えるプログラムを用意します。

はじめのimgはトップ画みたいなものがあったほうが良いかと思い追加しました。

n_imgはRSSのフィードを表示する際の背景となりますから、ニュース元のロゴ画像とか入れた画像を用意しておくと、それっぽく見えます。

その後、格納したタイトル、フィードを一つずつ読み出して表示します。
time.sleep(10)ごとにフィードは切り替わるので、お好みの時間に調整してください。

thread = threading.Thread(target=window)
thread.start()

repeat()

スレッドを起動してループを開始すればあとはオートで切り替わっていきます。

まとめ

とりあえずRSSからフィードを取得してそれっぽく表示することができました。

しかしニュースフィードから画像を取得する方法は全くわかっていないのでまだまだ改善の余地はあります(課金が必要かも?)。

放っておいてもずっと更新し続けるのですが、3日に1回ほど取得に失敗して何も表示しなくなるバグがあります。原因は不明です。止まったら再度起動しなおしてあげてください。

ちなみにこの電光掲示板を自宅に設置してみたところ、家族から「電車の中にいる気分になるからやめてほしい」と言われ、3日と持たず撤去されました。残念です。