😮

[Python]指定したWEBページからテキストを取得して音読してもらう[pyttsx3]

2024/10/03に公開

pyttsx3 を使えばPythonでも簡単に、しかもオフラインの環境でもテキストの音読できるスクリプトができました。しかし読み上げ対象となるテキストを毎回どこからかコピペしてきて指定するのは、正直言って面倒くさいですよね。なので、WEBページを指定して、そこから本文を自動的に抽出し、音読してもらうように改良しました。

pyttsx3を使った音声読み上げに関する基本の記事はこちらです。
https://zenn.dev/zenn24yykiitos/articles/c3ad2101993805

手順の概要

  1. ウェブスクレイピングで記事取得
  2. 取得した記事の読み上げ

読み上げ対象となる記事を指定し、そこから本文を抽出するためには、ウェブスクレイピングが必要です。そこで、BeautifulSoupやrequestsを使って、ウェブページから記事を取得します。次に、取得した記事をpyttsx3を使って音読します。

具体的な実装

1. ウェブスクレイピングで記事を取得

  • ライブラリのインストール
    まず、必要なライブラリをインストールします。ライブラリは以下のコマンドを実行することで導入できます。すでにインストール済みの場合は不要です。
pip install requests beautifulsoup4 pyttsx3

各ライブラリの簡単な説明です。
requests: ウェブページのHTMLを取得する。
BeautifulSoup: 取得したHTMLから記事の内容を解析し、必要なテキストを抽出する。
pyttsx3: テキストを音読する。

  • ニュースサイトから記事を取得する
    次に対象となるニュースサイトから記事を取得します。以下の例では、架空のニュースサイトの構造を想定しています。実際のニュースサイトのHTML構造に基づいて、適切にコードを調整する必要があります。
# 読み上げたいニュース記事のURLを指定する。
# ※ 下記はダミーのURLです。
url = 'https://example.com/news-article-url'
# ウェブページのHTMLを取得
response = requests.get(url)

# HTMLをBeautifulSoupで解析
soup = BeautifulSoup(response.content, 'html.parser')

# ニュース記事の本文が入っている要素を取得
# ※ここでは例として <div class="article-content"> を使っています
article = soup.find('div', class_='article-content') 

# 記事のテキストを取得
if article:
    return article.get_text(strip=True)
else:
    return "記事が見つかりませんでした。"

requestsを使って指定したURLのページを取得し、そのHTMLをBeautifulSoupで解析します。
記事本文が含まれているHTML要素(例: <div class="article-content">)を指定して、その内容を抽出します。実際のニュースサイトに応じて、この要素を変更する必要があります。

2. 取得した記事の読み上げ

取得した記事の内容をtext変数に格納し、pyttsx3で生成したengineに渡します。


import pyttsx3
engine = pyttsx3.init()

# 読み上げ速度と音量を設定
engine.setProperty('rate', 150)
engine.setProperty('volume', 0.9)

# 読み上げる
engine.say(text)
engine.runAndWait()

完成スクリプト

記事取得と読み上げ機能を関数化し、統合した全スクリプトは以下の通りです。

import requests
from bs4 import BeautifulSoup
import pyttsx3

# 記事の内容を取得する関数
def get_article_text(url):
    # ウェブページのHTMLを取得
    response = requests.get(url)
    
    # HTMLをBeautifulSoupで解析
    soup = BeautifulSoup(response.content, 'html.parser')
    
    # ニュース記事の本文が入っている要素を取得
    # ※ここでは例として <div class="article-content"> を使っています
    article = soup.find('div', class_='article-content') 
    
    # 記事のテキストを取得
    if article:
        return article.get_text(strip=True)
    else:
        return "記事が見つかりませんでした。"

# テキストを読み上げる関数
def read_text(text):
    engine = pyttsx3.init()

    # 読み上げ速度と音量を設定
    engine.setProperty('rate', 150)
    engine.setProperty('volume', 0.9)

    # 読み上げる
    engine.say(text)
    engine.runAndWait()

if __name__ == "__main__":
    # 読み上げたいニュース記事のURL
    # ※ 実際のニュース記事のURLを指定してください
    url = 'https://example.com/news-article-url'  

    # 記事の本文を取得
    article_text = get_article_text(url)

    # 記事を音読
    if article_text:
        print("記事を読み上げます。")
        read_text(article_text)
    else:
        print("記事の取得に失敗しました。")

urlには、実際に読み上げたいニュース記事のURLを指定します。スクリプトを実行すると、記事がコンソールに表示され、同時に音声で読み上げられます。

実際のサイトに合わせた調整方法

ニュースサイトごとにHTMLの構造は異なります。そのため、記事の本文がどのタグやクラスに含まれているかを調べる必要があります。ChromeやFirefoxの開発者ツール(F12キーを押して開く)を使って、特定の記事がどの要素に含まれているかを調べ、その要素をBeautifulSoupで指定する必要があります。

たとえば、zenn の記事ページであれば、
対象タグは<div class="View_main__AU6KW">あたりでしょうか。
get_article_text関数内のコードを次のように置き換えます。

article = soup.find('div', class_='View_main__AU6KW')

これで url をzennブログの記事に指定すると、本文のみを読み上げます。

url = 'https://zenn.dev/articles/037a9dbb3ff54f/'

Discussion