1
4

More than 3 years have passed since last update.

Webスクレイピングした情報をOpenJtalkで音声出力する

Last updated at Posted at 2020-03-07

今回は、Webスクレイピングして取得した株価をOpenJtalkを使ってRaspberry Piに話してもらいます。

この記事でできること

  1. Webスクレイピングする
  2. 取得した情報を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するコードになっています。
コードの意味については、こちらの記事にほぼ書いてあるので参照してください。

webscraping_test.py
#!/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を動かしている記事があったのでそれを使います。
先ほどと同じディレクトリーにこのコードをコピペするなり作成してください。

jtalk.py
#!/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

いよいよ組み合わせます。と言ってもほんの数行足すだけですが、、
できたコードがこちらです。

webscraping_jtalk_test.py
#!/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

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4