今回は、Webスクレイピングして取得した株価をOpenJtalkを使ってRaspberry Piに話してもらいます。
#この記事でできること
- Webスクレイピングする
- 取得した情報をRaspberry PiにインストールしたOpenJtalkで発話
#前提
・Raspberry PiでPython3とOpenJtalkが使える状態
(OpenJtalkのインストールはこの記事で解説しているのでまだの方はどうぞ!)
#動作環境
・Raspberry P i3 model B
・OS: Raspbian
・Python ver3.7
#1. 株価をWebスクレイピングして取得する
コードは以下の記事を参考にしています。
Python3でwebscraping : https://qiita.com/Senple/items/724e36fc1f66f5b14231
株価を取得: https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406
ここで一応、webスクレイピングは一歩間違えば法に触れる可能性があるので初めての方はこちらの記事を一読することをオススメします。
ではコードを書いていきます。
*全て適当な同じディレクトリーでファイルを作成していってください。
これは,Python3系で
日経新聞のサイトから株価を取得してprintするコードになっています。
コードの意味については、こちらの記事にほぼ書いてあるので参照してください。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import urllib3 #this is installed as default
from bs4 import BeautifulSoup
import certifi
#URL
url = "https://www.nikkei.com/markets/kabu/"
# URLにアクセスする htmlが帰ってくる → <html><head><title>経済、株価、ビジネス、政治のニュース:日経電子版</title></head><body....
html = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED',
ca_certs=certifi.where())
r = html.request('GET', url)
# htmlをBeautifulSoupで扱う
soup = BeautifulSoup(r.data, "html.parser")
# span要素全てを摘出する→全てのspan要素が配列に入ってかえされます→[<span class="m-wficon triDown"></span>, <span class="l-h...
#span要素-> p要素とdiv要素のように普通の文章を挿入する, 違いとしては改行がない
spans = soup.find_all("span")
for tag in spans:
# classの設定がされていない要素は、tag.get("class").pop(0)を行うことのできないでエラーとなるため、tryでエラーを回避する
try:
#tag.get("class") tagの中のクラスを全て取ってきてリストで返す
string_ = tag.get("class").pop(0)
if string_ in "mkc-stock_prices":
stockprice = tag.string
break
except:
pass
print(stockprice)
#2. openJtalkで音声出力させる
スクレイピングした情報をすぐ出力するためには、PythonからopenJtalkを動かす必要があります。(OpenJtalkのインストールはこちらから)
ということで、PythonからopenJtalkを動かしている記事があったのでそれを使います。
先ほどと同じディレクトリーにこのコードをコピペするなり作成してください。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
from datetime import datetime
def jtalk(t):
open_jtalk=['open_jtalk']
mech=['-x','/var/lib/mecab/dic/open-jtalk/naist-jdic']
htsvoice=['-m','/usr/share/hts-voice/mei/mei_normal.htsvoice']
speed=['-r','1.0']
outwav=['-ow','open_jtalk.wav']
cmd=open_jtalk+mech+htsvoice+speed+outwav
c = subprocess.Popen(cmd,stdin=subprocess.PIPE)
c.stdin.write(t.encode())
c.stdin.close()
c.wait()
aplay = ['aplay','-q','open_jtalk.wav']
wr = subprocess.Popen(aplay)
def say_datetime():
d = datetime.now()
text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
jtalk(text)
if __name__ == '__main__':
say_datetime()
あとは、webscarapingするコードの中でこのコードをimportして
jtalk.jtalk("発話させたいもの")とすれば音声出力できます!
#3. Webスクレイピング+openJtalk
いよいよ組み合わせます。と言ってもほんの数行足すだけですが、、
できたコードがこちらです。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#python3
#株価をスクレイピングしたやつをopenjtalkで音声出力する。
#web scraping
#今回はPython3で!!
##web scraping library####
import urllib3 #this is installed as default
from bs4 import BeautifulSoup
import certifi
### jtalk import
import jtalk #ここでimportしています!!
#URL
url = "https://www.nikkei.com/markets/kabu/"
# URLにアクセスする htmlが帰ってくる → <html><head><title>経済、株価、ビジネス、政治のニュース:日経電子版</title></head><body....
html = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED',
ca_certs=certifi.where())
r = html.request('GET', url)
# htmlをBeautifulSoupで扱う
soup = BeautifulSoup(r.data, "html.parser")
# span要素全てを摘出する→全てのspan要素が配列に入ってかえされます→[<span class="m-wficon triDown"></span>, <span class="l-h...
#span要素-> p要素とdiv要素のように普通の文章を挿入する, 違いとしては改行がない
spans = soup.find_all("span")
for tag in spans:
# classの設定がされていない要素は、tag.get("class").pop(0)を行うことのできないでエラーとなるため、tryでエラーを回避する
try:
#tag.get("class") tagの中のクラスを全て取ってきてリストで返す
string_ = tag.get("class").pop(0)
if string_ in "mkc-stock_prices":
stockprice = tag.string
break
except:
pass
jtalk.jtalk(str(stockprice)) #open j talkで音声出力する
#print(stockprice)
ディレクトリーに
jtalk.py
webscraping_jtalk_test.py
があることを確認したら以下を実行すれば話してくれます。
$ ls
jtalk.py webscraping_jtalk_test.py
$ python3 webscraping_jtalk_test.py
おお話した!
けど、数字を一つ一つ読み上げるだけですね。笑
とりあえずここまで出来ればいくらでも応用できると思います。
#まとめ
今回は,Webスクレイピング+OpenJtalkを試しました!
これでAPIで取ってきた情報なども同じように発話させることができますね。朝の決まった時間に動くようにプログラムを書いて天気とか自分の気になるニュースなどを読み上げさせたり、、
では!
[追記]
天気を喋るプログラムを以下の記事で書きましたので興味ある方はぜひ!
URL: https://qiita.com/coffiego/items/ec050e6106a7424c048b