あけましておめでとうございます。
最近、VOA Special English を聞いているのだが、サイトで提供されている Podcast は複数の記事をまとめて30分にしたてられているため、若干聞きにくい。またサイト上にあるスクリプトとの対応もわかりにくい。
http://www.voanews.com/specialenglish/ から個々の記事を開けば、スクリプトと音声ファイルの両方が取得できるので、ここから Podcast 用の RSS を起こせば、望むものが手に入りそうだ。
と思った瞬間に、きっとどこかの誰かが「それ Plagger で」と言ってそうな気がしたので、"voa plagger" でググってみる。ビンゴ(笑)。
- VOA News Special EnglishをトランススクリプトつきでPodcasting
- http://d.hatena.ne.jp/mteramoto/20061005/p1
ふむ、やっぱり Plagger ならできそうだ。
だが、使っているレンタルサーバに Plagger を入れようとしてすでに一度挫折している(Perl のバージョンがあわない……)。
ぜひ Plagger 教には入信したいと思う今日この頃なので、これを機に頑張ってみるのもいいのだが、自分はいかんせんこの手の依存関係のあるインストール話はいつも泥沼に陥りがち。
あれこれ奮闘したあげく、Plagger が動かないだけならまだしも、今まで動いていたものが動かなくなってしまうこともちらほら……
というわけで、Ruby でさっくり書いてみた(ruby1.8.4 で動作確認。1.8.2 以降なら動くかな?)。
筋の良くない「車輪の再発明」(発見とか勉強とか、プロセスに得るものがあまりない)なのでメリットはほとんどないのだが……強いてあげるなら、Ruby と標準ライブラリさえ入っていれば動くことと、「やっぱり Plagger の EntryFullText は強力やなあ」と実感できたことか?
なお、単語数が欲しいなあと思ったので、タイトルに "[371] The New Year Begins With Some Resolutions" という感じで先頭に単語数(適当に数えているので、誤差あり)が入るようにした。
あと、iPod nano の画面はやっぱり小さすぎて、スクリプトを見るにはちょっとつらい。できればスクリプトをもっと手軽にみられるようメールで自分宛に送るようにしたいところ。「それ、Pla(ry
【2007/04/13 追記】 ここで紹介しているスクリプトで生成した Podcast 用 RSS を 英語学習のページ にて配布してみている。「スクリプトなんか見てもしゃーないねん。Podcastのデータが欲しいねん」という方はそちらへどぞ。
なお、おそらく問題ないと思うのだが、万一なんらかの支障が発生した場合は仕様が変わったり無くなったりするかもしれない。念のため。
#!/usr/bin/ruby # VOA Special English Poscast Generator HOST = "www.voanews.com" PATH = "/specialenglish/customCF/RecentStoriesRSS.cfm?keyword=TopStories" require 'cgi' require 'date' require 'net/http' require 'rexml/document' require 'uri' def h(st) CGI::escapeHTML(st) end dom = Net::HTTP.start(HOST) do |http| response = http.get(PATH) REXML::Document.new(response.body) end puts <<HEAD <?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title>VOA Special English</title> <link>http://www.voanews.com/specialenglish/</link> <description>VOA Special English</description> <language>en</language> <pubDate>#{DateTime.now.strftime('%a, %d %b %Y %H:%M:%S %z')}</pubDate> HEAD itemlist = dom.elements.to_a('rss/channel/item') itemlist.each do |item| title = item.elements['title'].text link = item.elements['link'].text uri = URI.parse(link) xhtml = Net::HTTP.start(uri.host, uri.port) do |http| http.get(uri.path).body end body = if xhtml =~ /<span class="body">(.+?)<\/span>/mi then $1 else "" end mp3 = if xhtml =~ /<a href="(.+?)" class="media-asset"/i then $1 else "" end datetext = if xhtml =~ /<span class="datetime">(.+?)<\/span>/ then $1 else "" end body = body.gsub(/<.+?>/, '').gsub(/\n\n\n+/, "\n\n").gsub(' ', ' ') date = Date.parse(datetext.gsub(/<.+?>/, '')) wordcount = body.scan(/\w+/).length puts <<ITEM <item> <title>[#{wordcount}] #{h title}</title> <link>#{h link}</link> <pubDate>#{date.strftime('%a, %d %b %Y %H:%M:%S %z')}</pubDate> <dc:creator>VOA</dc:creator> <dc:subject>English</dc:subject><dc:subject>News</dc:subject> <description><![CDATA[ #{body} ]]></description> <enclosure url="#{h mp3}" length="" type="audio/mpeg" /> </item> ITEM end puts <<FOOT </channel> </rss> FOOT