1. Mechanetai

    Posted

    Mechanetai
Changes in title
+ゆっくりに青空文庫を読んでもらう:もっと精確に
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,133 @@
+[前回]()はPythonを使って、ゆっくりに青空文庫を読んでもらうことに成功しました
+しかし、ルビを考慮せず読ませてしまったので、読み上げの精度がかなり低いという難点がありました
+今回はその点を修正していきます
+
+#今回の流れ
+
+やりたいことは
+**青空文庫のURLを投げると、読みの辞書登録を済ました上でゆっくりが読み上げてくれる**ことです
+そこで、以下の流れを作っていきます
+
+![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349064/40c261fe-2873-a925-3445-be37e6a8478b.png)
+
+# 図書カードのURLからファイルのURLを取得
+
+青空文庫には図書カードというページがあり、そこから本文が記載されたWebページに飛んだり、各種ファイルをDLできたりします
+
+![tosyoka-do.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349064/97a483d2-cb4e-a1fd-ea59-c8f9be7a8f3d.png)
+
+今回は赤く囲ったところのファイルの内、zipとxhtmlがほしいので、BeautifulSoup4を使って取得します
+
+```python:aozora_urlsplit.py
+from bs4 import BeautifulSoup
+import requests
+import re
+
+def aozoraurl(url):
+ page = requests.get(url)
+ soup = BeautifulSoup(page.content, 'html.parser')
+
+ table = soup.select('table.download a[href*=".html"]')
+ htmlurl_rel = str(table).split('\"')[1].replace("./", "/")
+ # XHTMLの相対パス取得
+
+ table2 = soup.select('table.download a[href*=".zip"]')
+ zipurl_rel = str(table2).split('\"')[1].replace("./", "/")
+ # zipファイルの相対パス取得
+
+ urlsplit = re.sub("/card[0-9]*.html", "", url)
+ htmlurl = urlsplit + htmlurl_rel
+ zipurl = urlsplit + zipurl_rel
+ aozoraurllist = [htmlurl, zipurl]
+ #入力したURLのcard以下を切り取り、上の相対パスとくっつける
+
+ return aozoraurllist
+
+if __name__ == '__main__':
+ print(aozoraurl("https://www.aozora.gr.jp/cards/000879/card85.html"))
+
+```
+
+図書カードのページのURLを投げると[XHTMLのURL, zipのURL]のリストを返してくれます
+
+# ルビのリストを作成する
+
+XHTMLからルビのリストを作成します
+
+```python:aozora_rubylisting.py
+from bs4 import BeautifulSoup
+import requests
+import re
+import jaconv
+
+def aozoraruby(url):
+ page = requests.get(url)
+ soup = BeautifulSoup(page.content, 'html.parser')
+
+ _ruby = soup.select("ruby")
+
+ _rubylist = []
+ for i in _ruby:
+ _ruby_split = re.sub("<[/a-z]*>", "", str(i)).replace(")", "").split("(")
+ _rubylist.append(_ruby_split)
+
+ for index, item in enumerate(_rubylist):
+ _rubylist[index][1] = jaconv.kata2hira(str(item[1]))
+
+ return _rubylist
+
+if __name__ == '__main__':
+ print(aozoraruby("https://www.aozora.gr.jp/cards/000879/files/3813_27308.html"))
+```
+
+SofTalkはひらがなでしか読み登録できないので、カタカナはひらがなに変換します
+
+今回始めて `enumerate` を使ったのですが、スマートで良いですね
+
+# txtファイルから本文を作成
+
+前回同様、[青空文庫からPythonで本文を取得したい - AI人工知能テクノロジー](https://newtechnologylifestyle.net/711-2/)からお借りします。
+
+`download()` 関数にURLを投げると `convert()` 関数から本文が返ってきます
+`main()` 関数は使わないので `if __name__ == '__main__':`以下に置いておきます
+
+# ゆっくりの辞書登録と読み上げ
+
+```python:aozora_yukkuri.py
+import subprocess
+import os
+
+from aozora_urlsplit import aozoraurl
+from aozora_rubylisting import aozoraruby
+from aozora_honbun import download, convert
+
+os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+urllist = aozoraurl("https://www.aozora.gr.jp/cards/000879/card3813.html")
+
+_ruby = aozoraruby(urllist[0])
+_honbun = convert(download(urllist[1])).splitlines()
+
+_start = "start SofTalk.exeのPath"
+_pron = "/P:"
+_speed = "/S:120"
+_word = "/W:"
+
+for j in _ruby:
+ _command_ruby = [_start, _pron + j[1] + "," + j[0] + ",True"]
+ print(_command_ruby)
+ subprocess.run(' '.join(_command_ruby), shell=True)
+
+for i in _honbun:
+ _command = [_start, _speed, _word + i]
+ subprocess.run(' '.join(_command), shell=True)
+```
+
+本文を改行ごとにリストに入れて、辞書登録から本文読み上げまで行います
+
+ゆっくりの声変えたい場合は`_command`に`/M:`もしくは`/MN:`を付け足して変更してください(参考[^dai1kai])
+
+
+
+[^dai1kai]: Pythonでゆっくりボイスを作ろう
+ https://qiita.com/Mechanetai/items/78b04ed553cce01fa081