ラズパイ:PythonでYahoo!の天気予報をしゃべらせる

ラズベリーパイのロゴ Raspberry Pi

わたしは毎朝6時にYahoo!天気・災害のサイトから情報を取得して、ラズパイに天気予報をしゃべらせています。
その方法を解説します。

必要なもの

  • Raspberry Pi
  • Python3(プログラミング言語)
  • Beautiful Soup(Pythonの外部ライブラリ)
  • AquesTalk Pi(ラズパイで音声合成できるライブラリ)

Raspberry Piを利用しているなら、すでにPython3はインストールされているはずですので、インストールが必要なものとしては、Beautiful SoupAquesTalk Piとなります。

考え方としては、Python3+Beautiful Soupで作ったプログラムからYahoo!の天気予報サイト情報をスクレイピング取得。文字列化した天気予報をAquesTalk Piに渡してしゃべらせます。

天気予報を取得するURLをチェックしておく

スクレイピングという技術を使ってサイトの文字情報から必要な情報のみを抜き出します。
天気予報には、都道府県ごとに地域がありますので、Yahoo!天気・災害のトップページにまずアクセスすます。

下にスクロールすると都道府県ごとのリンクがあるので取得したい地域をクリックしてください。

最終的に以下のように都道府県ごとの各地域までたどって今日明日の天気が表示されるページを開いてください。

このときブラウザに表示されるURLを控えておきます。

例)水戸地方の場合

北部(水戸)の天気 - Yahoo!天気・災害
北部(水戸)の天気予報。今日・明日の天気と風と波、明日までの6時間ごとの降水確率と最高・最低気温を見られます。

AquesTalk Piの準備

AquesTalk Piはラズパイで無償利用できる音声合成ライブラリです。
以下からダウンロードできます。

AquesTalk Pi - Raspberry Pi用の音声合成アプリ
AquesTalk Piを使えば、Raspberry Piで簡単に音声合成できます

ダウンロードしたファイルはtgz形式なので、以下のコマンドでラズパイの適当な位置でターミナルから解凍してください。

tar zxvf ファイル名

解凍したフォルダ内にあるAquesTalkPiというファイルが実行ファイルになります。

例えばターミナルから

./AquesTalkPi "おっす!おら悟空。" | aplay

などとラズパイにしゃべらせてみることができます。(もちろんスピーカをつないでください)

Pythonからしゃべらせるにはos命令を使って簡単にできます。
os命令は通常ターミナルからできることをPython側から呼び出すことが出来る命令です。
今回のスクリプトではこんな感じで利用しています。(weatherという文字列の内容をしゃべらせる場合)

#しゃべる
cmd = "/home/pi/aquestalkpi/AquesTalkPi " + weather + " -s 90 | aplay"
os.popen(cmd).readline().strip()

プログラムの準備

プログラムはPython3で作成します。
Python3で利用するライブラリBeautiful Soupをまだインストールしていない方は、ターミナルを起動しpipコマンドでインストールしてください。

pip3 install bs4

次にPythonスクリプトの準備です。

以下で紹介するスクリプトは水戸地方の天気予報のため、12行目のURL部分は先ほどチェックしたURLを、41行目の文字列「水戸地方~」の部分は、取得する地域の情報に置き換えて修正してください。
また、58行目のAquesTalkPiのラズパイ上のディレクトリも適宜置き換えてください。

speakWeather.py

#!/usr/bin python3
# -*- coding: utf-8 -*-
import urllib.request
from bs4 import BeautifulSoup
import re
import os

"""
	お天気情報をサイトから取得する
"""
# Yahoo!のページから水戸の天気を開く
url = "https://weather.yahoo.co.jp/weather/jp/8/4010.html"
data = urllib.request.urlopen(url)

# HTMLを解析して取得
soup = BeautifulSoup(data, 'html.parser')

# classが 'forecastCity' のタグを取得
tenkiAll = soup.find(class_="forecastCity")

date = tenkiAll.find(class_="date")
date = re.sub('\)', '曜日', date.text)	# 「曜日」を追加

tenki = tenkiAll.find(class_="pict")

high = tenkiAll.find(class_="high")
low = tenkiAll.find(class_="low")

# 先頭の気温(数値)のみ取り出す正規表現 例)highの内容が 29℃[-2] のような値のため
regexp = re.compile("^\-[0-9]+|^[0-9]+")	# 先頭がマイナスの数値とプラスの数値の両方に対応

# 最高気温と最低気温の数値のみを取り出す
high = regexp.search(high.text)
low = regexp.search(low.text)

"""
	天気予報文字列を整形
"""
# 天気をしゃべるテキストを設定
weatherText =  "ラズパイ天気情報。{}。".format(date)
weatherText += "水戸地方、今日は、{}。".format(tenki.text)
weatherText += "最高気温は、{}度、".format(high.group())
weatherText += "最低気温は、{}度、でえええす".format(low.group())

# 全体の文字列置換:改行・空白文字・特殊文字'('や')'などを消す
weatherText = re.sub('\n| |\(|\)', '', weatherText)

"""
	しゃべるために文字列を置換
"""
weatherText = re.sub('時々', 'ときどき', weatherText) #読みが変になるため置換
weatherText = re.sub('雨', 'あめ', weatherText)
weatherText = re.sub('雪', 'ゆき', weatherText)

weatherText = re.sub('-', 'マイナス', weatherText )	# 気温がマイナスの場合
print(weatherText)

# 天気をしゃべる
cmd = "/home/pi/aquestalkpi/AquesTalkPi '{}' | aplay".format(weatherText)
result = os.popen(cmd).readline().strip()


実行方法

ターミナルから以下のコマンドで実行します。

sudo python3 speakWeather.py

実行イメージ

ターミナルに天気予報が表示され、スピーカーから音声が流れたら成功です。

動かない場合は、エラーメッセージをよく読みましょう!

crontabでプログラムを定時実行する

わたしの場合、毎朝6時に天気予報をしゃべらせています。

ターミナルから

sudo crontab -e

としてcrontabを起動し、以下のように設定しました。(スクリプトが/home/piにあると仮定)

0 6 * * * sudo python3 /home/pi/speakWeather.py

crontabの起動時刻等の設定方法は以下を参考になさってください。

cronの日時指定を、基礎から学ぶ(分,時,日,月,曜日の指定、◯分ごと、月末起動、など) - YoheiM .NET
cronの日時指定を、基礎から学ぶ(分,時,日,月,曜日の指定、◯分ごと、月末起動、など)今日は、cronの時間指定について基礎〜応用まで、ブログに書きたいと思います。

以上、ラズパイ:PythonでYahoo!の天気予報をしゃべらせるでした。

コメント

タイトルとURLをコピーしました