Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

EPW | 英単語発音管理用スクリプト EPWを実装してみた

概要

英単語発音管理用スクリプト EPWを実装してみた

詳細

要約

英単語の発音記号・音声ファイルをWeblioさんのサイトから取得して
HTMLのリストにするシステムです。
尊敬の念を込めて「English」と「Pronunciation」と「Weblio」の頭文字をとって
EPWをシステム名とします。

仕様

Rubyで構築します
・登録する単語は設定ファイルで管理(epw.words).1行1単語で並べただけのファイル。
・単語の登録にはCUIを利用します。
 コマンド例
 `ruby epw.rb`
・コマンドを実行すると、該当単語を元にWeblioさんのサイトをスクレイピングして
 発音記号と音声ファイル(wav)をダウンロードします。
・アクセスするURL
 `http://ejje.weblio.jp/content/登録する単語名`
 上記のURLは後ほど作成するhtml内からアクセス出来るようにします。
・発音記号の取得
 b#KejjeHtの中のテキストを取得
・音声ファイルのダウンロード
 div#ePsdDlをスクレイピングし、onclickに指定されている
 return playSwfSound('http://www.westatic.com/wbr/CHUJITEN/', 'S-D28A77C_E-D28C7DA', 'ePsdDl', false, true)
 から「S-D28A77C_E-D28C7DA」を取得。※ここでは単語によって左記の文字列は変わります。
 発音ファイルダウンロード用の基礎URLに上記をプラスして音声ファイルをダウンロード。

 `http://www.westatic.com/wbr/CHUJITEN/S-D28A77C_E-D28C7DA.wav`

 上記URLからダウンロードして保存する。
 保存時は分かりやすいように
 単語名.wav
 に変更。

 epw.rbがあるフォルダをルートとして
 %root%pronunciation
 に保存する。

 ※上記のような処理の都合上、Weblioさんがホームページ内のhtmlの仕様を変更したらこのスクリプトは動作しなくなります。

・HTML形式で出力する
 %root%epw.html
 として出力する。

関連ファイル構成

※base,vaseを単語指定して出力した後の場合

│  epw.css
│  epw.html
│  epw.html.template
│  epw.rb
│  epw.words
│
└─pronunciation
       base.wav
       vase.wav
ファイル名 内容
epw.css 任意のCSS。好きな内容で見栄えを調整してください
epw.html epw.rbを実行すると出力される「英単語発音管理」画面
epw.html.template 「英単語発音管理」画面のテンプレート。
epw.words 単語管理ファイル。このファイルに改行区切りで追加した単語が「英単語発音管理」画面への出力対象になります
pronunciation Weblioからダウンロードしたwavファイル置き場

ソースコード

epw.rb
# encoding: utf-8
require "erb"
require "open-uri"
require "nokogiri"
require "pp"

class Epw
  WEBLIO_URL = "http://ejje.weblio.jp/content"
  PRONUNCIATION_XPATH = "//b[@class='KejjeHt']"
  WMV_URL1 = "http://www.westatic.com/wbr/CHUJITEN"
  WMV_URL2 = "http://ejje.westatic.com/audio/"
  WMV_XPATH = "//div[@id='ePsdDl']"

  def output_html
    get_words
    sort_words
    base_html = get_html_template
    words_htmls = get_words_htmls
    html = get_html(base_html, words_htmls)
    output html
  end

  private
  def get_words
    @words = File.open("epw.words", "r") {|f|f.read}.split("\n")
    if @words.size == 0
      puts "no word in epw.words"
      exit
    end
  end

  def sort_words
    @words.sort!
  end

  def get_html_template
    File.open("epw.html.template", "r") {|f|f.read}
  end

  def get_words_htmls
    htmls = []
    @words.each {|w|htmls << append_word(w)}
    htmls
  end

  def append_word(word)
    word_template =<<-EOS
    <tr>
      <td><%=word%></td>
      <td><%=pronunciation%></td>
      <td><a href="<%=weblio_url%>" target="_blank">weblio url for "#{word}"</a></td>
      <td><a href="pronunciation/#{word}.wav" target="_blank">play pronunciation ["#{word}"]</a></td>
    </tr>
    EOS
    pronunciation = get_pronunciation(word)
    weblio_url = get_weblio_url(word)
    get_wav(word)
    erb = ERB.new(word_template)
    erb.result(binding)
  end

  def get_html(base_html, words_htmls)
    base_html.gsub(/%contents%/, words_htmls.join("\n"))
  end

  def get_pronunciation(word)
    page = URI.parse("#{WEBLIO_URL}/#{word}").read
    @document = Nokogiri::HTML(page)
    @document.xpath(PRONUNCIATION_XPATH).first.text.gsub("/", "")
  end

  def get_weblio_url(word)
    "#{WEBLIO_URL}/#{word}"
  end

  def get_wav(word)
    @document.xpath(WMV_XPATH).to_s =~ /playSwfSound\('http:\/\/www\.westatic\.com\/wbr\/CHUJITEN\/', '(.*?)'/
    match = Regexp.last_match
    if match.nil?
      @document.xpath(WMV_XPATH).to_s =~ /playSwfSound\('http:\/\/ejje\.westatic\.com\/audio\/', '(.*?)'/
      match = Regexp.last_match
      base = WMV_URL2
    else
      base = WMV_URL1
    end
    open("#{base}/#{match[1]}.wav") do |source|
      open("pronunciation/#{word}.wav", "w+b") do |o|
        o.print source.read
      end
    end
  end

  def output(html)
    File.open("epw.html", "w") do |f|
      f.puts html
    end
  end
end

epw = Epw.new
epw.output_html
epw.html.template
<!doctype html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" type="text/css" href="epw.css" />
  <title>EPW</title>
</head>
<body>
  <h1>EPW</h1>
  <hr>
  <table>
    <tr>
      <th>word</th>
      <th>pronunciation</th>
      <th>weblio url</th>
      <th>wav</th>
    </tr>
    %contents%
  </table>
</body>
</html>
epw.words(内容はサンプル)

ここに好きな単語を登録します。
私がvとb、sとth、zとthの聞き分けが苦手であることが分かる内容です・・・

vase
base
breeze
breath
sink
think
useful
youthful
mouse
mouth

出力画像サンプル