Raspberry Piで決まった時間にニュースを送る方法を解説します。
Raspberry Piに限らず、WindowsやMacでも可能ですが、Raspberry Piは消費電力が少ないため、簡単なサーバーとして動かす有用性が生きてきます。
Raspberry Piは、つけっぱなしでも電気代は、一ヶ月程で50円程度くらいになります。
ここではRaspberry Piの電源を常時つけて、決まった時間にKindleへニュースを送ります。
また、Kindleへの送信だけでなく、メールが受信できる環境であれば、ニュースの自分のスマートフォンなどへ送ることができます。
kindleについて
kindleはAmazonで購入した本を読むだけでなく、ユーザが好きなファイルをkindleに送り閲覧することができます。kindleは、Word、HTML、MOBI、ePub、RTF、TXT、Adobe PDFといった多彩なフィアル形式をサポートしています。
Kindleを購入する人は、Wifiモデルを購入する人が多いようです。3Gモデルならば、自宅外でもコンテンツのダウンロードが行えますが、Wifiモデルでは行えません。また、ネットワーク通信を使うと、バッテリの消耗が激しいため、Wifiモデルであろうとネットで最新のニュースを閲覧するには、Kindleは向いていません。
そのため、ここでは毎朝、RaspberryPi上でプログラムを実行させ、Kindleに向けてニュースを送信します。これにより、通勤途中の電車の中で、Kindleを使い、ニュースを読むことができるようになります。
ここでは、英語の勉強もかねて、英語のニュースをkindleに送るプログラムを作成します。
英語のニュースは、JapanTodayから取得します。
JapanTodayのニュースは、比較的簡単で短いので、英語の勉強に最適かと思います。
Kindleの設定
Kindleにメールでファイルを送るには、Amazonでの設定が必要になります。
まずは、Amazon上で設定を行います。
Amazonのアカウントサービスからコンテンツの端末と管理を選択します。
「コンテンツと端末の管理」の画面では、Kindleの設定が行えます。
設定のタブの「パーソナル・ドキュメント設定」からKindleへのSend-to-Kindle Eメールアドレスを確認します。
また、「パーソナル・ドキュメントの保存」を有効に変更します。
「承認済みEメールアドレス一覧」に送信元のEメールアドレスを登録します。ここで登録したEメールアドレスからしかKindleへメールを遅れません。
KindleでのHTML
Kindleで使えるHTMLフォーマットは「基本的なHTMLのフォーマットのガイドライン」を参考にしましょう。
ここでは、ニュースの区切れを改ページで区切るため、以下のタグを使用します。このタグはKindle専用の特別なタグになります。
<mbp:pagebreak/>
Pythonプログラムでの実行
プログラムは以下の順で実行します。
0.決まった時間にプログラムを動かす
1.RSSからコンテンツのURLを取得
2.URLを指定して、Webページを取得
3.Webページから、タイトルとニュース内容を抽出
4.抽出した情報からHTMLファイルを作成
5.HTMLファイルを添付してkindleに送信
0.決まった時間にプログラムを動かす
決まった時間にプログラムを動かすのは、cronを使用します。
「決まった時間に処理する」のページを参考に、24時間に一回サイトからニュースを取得し、メールに添付して送信します。
1.RSSからコンテンツのURLを取得
「RSSを取得する」を参考に、RSSからコンテンツの情報を取得します。
2.URLを指定して、Webページを取得
「Webページを取得する」を参考に、URLを指定して、Webページを取得します。
3.Webページから、タイトルとニュース内容を抽出
「Web(HTML)から情報を抽出する」を参考に、取得したWebページから情報を抽出します。
4.抽出した情報からHTMLファイルを作成
「テンプレートからファイル生成」を参考に、抽出した情報とテンプレートを組み合わせて、HTMLファイルを生成します。
5.HTMLファイルを添付してkindleに送信
「Gmailで簡単にメール送信」を参考に、HTMLファイルを添付して、GmailでKindelへ送信します。
上記を含めたサンプルプログラムは以下になります。
サンプルプログラムのkindleアドレスを変更して、Pythonプログラムとして実行するとニュースを取得後、Kindleへ送信されます。JapanToday以外のニュースを取得する場合は、HMTLファイルからの抽出方法を変更する必要があります。
#!/usr/bin/env python # -*- coding: utf-8 -*- import feedparser import requests import lxml.html import gmail import re import os from time import mktime from datetime import datetime #Kindleのアドレス KINDLE_ADDRESS = "XXXXXXXXXXXXXX@kindle.com" class News: """ ニュースを格納するクラス """ def __init__(self, title, content, url, date): self.title = title self.url = url self.date = date self.content = content def showinfo(self): print '%s (%s)' % (self.title, self.date) def create_html(list, filename): from jinja2 import Environment, FileSystemLoader path = os.path.abspath(os.path.dirname(__file__)) env = Environment(loader=FileSystemLoader(path, encoding='utf8')) tpl = env.get_template('template.html') news_list = [] for news in list: content = news.content news_list.append({'title':news.title, 'body':content}) #現在時刻を取得 now = datetime.today() title = now.strftime("News_%Y-%m-%d_%H:%M:%S") html = tpl.render({'title':title, 'news_list':news_list}) tmpfile = open(path + "/" + filename, 'w') #書き込みモードで開く tmpfile.write(html.encode('utf-8')) tmpfile.close() if __name__ == '__main__': #RSSのURL rss_url = "http://www.japantoday.com/feed/" #interval_time時間以内のニュースを取得 interval_time = 24 #空のNewsリスト news_list = [] #現在時刻を取得 now = datetime.today() feed = feedparser.parse(rss_url) for entry in range(len(feed.entries)): #RSSの内容を一件づつ処理する title = feed.entries[entry].title link = feed.entries[entry].link #現在時刻から更新日時の時間差を確認 tmp = feed.entries[entry].updated_parsed date = datetime.fromtimestamp(mktime(tmp)) diff_time = now - date diff_hours = (diff_time.seconds/3600) + (diff_time.days*24) if diff_hours <= interval_time: #interval_time時間以内に更新された記事のみを対象とする #Webページ(HTML)の取得 req = requests.get(link) root = lxml.html.fromstring(req.text) #HTMLから記事の抽出(Japan Today) title = root.get_element_by_id('main_title').text content = lxml.html.tostring(root.get_element_by_id('article_content')) p = re.compile(r"<[^>]*?>") content = p.sub("", content) #記事リストの中に追加 news = News(title, content, link, date) news_list.append(news) filename = now.strftime("News_%Y-%m-%d_%H:%M:%S") + ".html" create_html(news_list, filename) #メッセージの作成 to_addr = KINDLE_ADDRESS subject = filename body = "" mime={'type':'text', 'subtype':'comma-separated-values'} attach_file={'name':filename, 'path':filename} msg = gmail.create_message(gmail.ADDRESS, to_addr, subject, body, mime, attach_file) #メールの送信 gmail.send(gmail.ADDRESS, [to_addr], msg)
Kindleには以下のテンプレートを適応して、メールに添付しています。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>{{title}}</title> </head> <body> {% for news in news_list %} <h1>{{ news.title|safe }}</h1> {{ news.body|safe }} <mbp:pagebreak/> {% endfor %} </body> </html>
プログラムを実行すると、ニュースをKindleに送信します。