自分でニュースソースを追加する(その2)
今回は前回 の続きで、Pythonのコードを使って新しいニュースサイト用のレシピを作り、Calibreに追加してみましょう。CalibreのマニュアルにもAdding your favorite news website と言うチュートリアルがあり、これも非常に参考になりますが、ここでは実際にgihyo.jpを例にして、最新の記事数本を電子書籍に変換するまでを実際に作ってみます。
新しいレシピを作成するには、前回と同様、「 ニュース取り込み」から「独自ニュース源を追加」のダイアログを開き、そこで(今回は)右上にある「アドバンスモードに切り替え」のボタンを押すとPythonスクリプトのレシピを入力できるようになります。
アドバンストモード
前回も少し言及しましたが、Calibreのニュース・レシピはPythonで書き、スクリーン・スクレイピング用のライブラリ、Mechanize ( Cookieの処理や、ログイン等のフォームの操作等を行う)とBeautifulSoup ( HTMLを解析しそれを操作する)を使ってニュースを取得します。レシピのスーパークラスBasicNewsRecipe にすでに色々な機能が含まれているので、ポイントを押さえてゆけばニュースソースの対応処理部分だけに集中して作成でき、シンプルに作成できるでしょう。
レシピの処理全体の流れを大まかに説明すると、次のようになります。
ログイン等を行う
記事のインデックスを取得する
各記事を取得する
記事HTMLを修正する
順を追って説明していきましょう。
1:(必要な場合)ログイン等を行う
get_browser メソッドでMechanizeの機能を使いログイン等を行います。多くのニュースサイトではログインしないと記事が見れない、一部の機能が使えないなどの制限があります。特に電子書籍に向いた印刷用ヴァージョンを見るためには、ログインが必要なことがよくあります。MechanizeはCookieの処理や、フォームの操作等ができるので、これを使って後の操作のためにログインします。今回のgihyo.jpレシピではログイン等は必要ないのでこのメソッドは使いません。
2:記事のインデックス(一覧)を取得する
parse_index メソッド等で記事のインデックスを取得・作成してどの記事をダウンロードするかを決定します。一覧ページをBeautiful Soupを使ってスクレイピングしても良いのですが、多くの場合、最新の記事は(全文でない)RSSフィードが出ている場合が多いため、それを使うことでBasicNewsRecipe側で勝手に記事一覧を作ってくれます(もちろん前回紹介したように、全文RSSがあればPythonでレシピを書く必要はありません) 。
#links to RSS feeds
feeds = [ ('gihyo.jp', u'http://gihyo.jp/feed/atom') ]
そのため今回は、gihyo.jpのRSSフィードをfeeds 変数に設定するのみで、parse_indexメソッドも使いません。
3:各記事を取得する
各記事の取得もBasicNewsRecipeクラスが自動でやってくれるのですが、今回のgihyo.jpでは記事が複数ページに分かれている場合があるため、preprocess_html と言うフック・メソッドをオーバーライドして、自作のメソッド append_page()にて再帰的に複数ページに対応します。その他(今回は使いませんが) 、プリント用ページ等に対応する時にはprint_version と言うフックも使えます。
#load second and subsequent page content
# in: soup - full page with 'next' button
# out: appendtag - tag to which new page is to be added
def append_page(self, soup, appendtag):
# find the 'Next' button
nextButton = soup.find(attrs={'rel':'next'})
if nextButton:
nexturl = nextButton['href']
soup2 = self.index_to_soup(nexturl)
print " fetching next url : " + nexturl
contents = soup2.find('div', attrs={'class':'readingContent01 autopagerize_page_element'})
pos = len(appendtag.contents)
appendtag.insert(pos, contents)
self.append_page(soup2, appendtag)
def preprocess_html(self, soup):
contents = soup.find('div', attrs={'class':'readingContent01 autopagerize_page_element'})
self.append_page(soup, contents)
return soup
4:記事HTMLを修正する
取得した記事には広告や、Twitter等へのリンク、パンくずリンク等の電子書籍として読むには必要ないものが数多く入っているので、それを修正します。これにはBasicNewsRecipeが勝手に行ってくれる便利な変数、remove_tags やremove_tags_before 、remove_tags_after 等があるので、これらに条件を設定するだけでOKです。今回は使いませんが、この他にも色々な修正処理を行う物があります。たとえばCSSを追加するextra_css 、リンクを有効・無効化するmatch_regexps やfilter_regexps 、そしてHTMLを強制的に正規表現で書き換えるpreprocess_regexps なども使用可能です。
remove_tags_before = dict(name='div', attrs={'id':['content']})
remove_tags = [
dict(name='div', attrs={'class':['pageSwitch01']}),
dict(name='div', attrs={'id':['socialBookmark']}),
dict(name='div', attrs={'class':['pageSwitch01 autopagerize_insert_before']})
]
remove_tags_after = [
dict(name='div', attrs={'id':['relArticle']})
]
仕上げ
あとは、名前など、レシピとして体制を整えるためにいくつかの変数を設定しましょう。
class Gihyo(BasicNewsRecipe):
title = u"gihyo.jp"
__author__ = 'Ado Nishimura'
description = u"gihyo.jp new articles"
language = 'ja'
no_stylesheets = True
remove_javascript = True
use_embedded_content = False
cover_url = 'http://image.gihyo.co.jp/assets/templates/gihyojp2007/image/header_logo_gihyo.gif'
これで、レシピのコードは一通りできあがりました。今回作ったレシピファイルは以下のとおりです。
これをCalibreで実行すると、完成したレシピが動作するようになって、gihyo.jpの内容をKindle等で見れるようになります。
Kindleで読むgihyo.jp
TIPS:レシピをコマンドラインからデバッグする
さて、これでレシピが上手く動けば問題ないですが、たいていはデバッグが必要です。これはGUIから行うと何度もダイアログを行き来して大変ですよね。ここではCalibreをインストールすると同時にインストールされる、コマンドラインツールを使ってデバッグする方法を紹介しましょう。
ebook-convert gihyo.recipe .mobi --test -vv -ddebug
ebook-convert は電子書籍のフォーマットをコンバートするためのコマンドライン・ツールですがニュース機能にも対応していて、元データの部分にレシピを指定するとレシピを実行・ダウンロードして指定したフォーマットに出力する所までやってくれます。--testオプションを指定すると最初の2記事しかダウンロードしないため、処理が速く終わります。-ddebug オプションはdebugと言うディレクトリを作り、その中に変換途中の各パイプラインの出力を書き出します。レシピのデバッグの場合には、ダウンロードされて整形された直後のHTMLデータがdebug/inputディレクトリの中に書き出されます。今回は使いませんがその他にも、便利なオプション があります。例えば --username USERNAME --password PASSWORDなどはログインが必要なレシピをデバッグする時に重宝します。
TIPS 2:自作のレシピをCalibreと一緒に配布してもらう
自分で作ったレシピが、他の人にも有用だと思われる場合には、Calibreのビルトイン・レシピとして配布してもらうこともできます。これは現在のところ、作者のKovid Goyalさんにお願いして入れてもらうと言うアナログな方法が取られていますが、mobileread.comと言う英語サイトにCalibreのレシピのフォーラム があるので、そこに投稿するとKovidさんが見てCalibreに取り込まれる、と言う方法が良く使われています。余談ですがこのmobileread.comと言うサイトは電子書籍関係のフォーラムとしては結構繁盛しているサイトで、Calibreは全面的にこのサイトでディスカッションの場所 を使用しているようです。興味ある方は一度見てみると良いかもしれません。