オープンソースの電子書籍管理ソフト「Calibre」を使いこなそう!

第3回Calibreに新しいニュースサイトを追加する

自分でニュースソースを追加する(その2)

今回は前回の続きで、Pythonのコードを使って新しいニュースサイト用のレシピを作り、Calibreに追加してみましょう。CalibreのマニュアルにもAdding your favorite news websiteと言うチュートリアルがあり、これも非常に参考になりますが、ここでは実際にgihyo.jpを例にして、最新の記事数本を電子書籍に変換するまでを実際に作ってみます。

新しいレシピを作成するには、前回と同様、⁠ニュース取り込み」から「独自ニュース源を追加」のダイアログを開き、そこで(今回は)右上にある「アドバンスモードに切り替え」のボタンを押すとPythonスクリプトのレシピを入力できるようになります。

アドバンストモード
アドバンストモード

前回も少し言及しましたが、Calibreのニュース・レシピはPythonで書き、スクリーン・スクレイピング用のライブラリ、Mechanize ⁠Cookieの処理や、ログイン等のフォームの操作等を行う)BeautifulSoup ⁠HTMLを解析しそれを操作する)を使ってニュースを取得します。レシピのスーパークラスBasicNewsRecipeにすでに色々な機能が含まれているので、ポイントを押さえてゆけばニュースソースの対応処理部分だけに集中して作成でき、シンプルに作成できるでしょう。

レシピの処理全体の流れを大まかに説明すると、次のようになります。

  1. ログイン等を行う
  2. 記事のインデックスを取得する
  3. 各記事を取得する
  4. 記事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_tagsremove_tags_beforeremove_tags_after等があるので、これらに条件を設定するだけでOKです。今回は使いませんが、この他にも色々な修正処理を行う物があります。たとえばCSSを追加するextra_cssリンクを有効・無効化するmatch_regexpsfilter_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
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は全面的にこのサイトでディスカッションの場所を使用しているようです。興味ある方は一度見てみると良いかもしれません。

おすすめ記事

記事・ニュース一覧