View All Posts. MiCHiLU.com powered by Django ;-)

[Python]: Python版Plagger pyhabuのpluginを作ってみる

pyhabu のpluginsを作ってみる。 常山フィード を1リンクにつき1エントリへ分解する。

まず、XML parserを用意します。 処理速度重視の lxml と、インストールがらくちんな BeautifulSoup を。

lxmlを使ってみる

>>> from lxml import etree
>>> from StringIO import StringIO
>>> parser = etree.HTMLParser()
>>> html = '<html><head><title>test<body><h1>page title<a href="url">TEST</a></h3>'
>>> tree = etree.parse(StringIO(html), parser)
>>> anchor = tree.xpath("//*[@href]")
>>> anchor[0].attrib.get("href")
'url'
>>> anchor[0].text
'TEST'

HTMLParser を使うと多少いい加減なHTMLでもそれなりに解釈します。 tree.xpath("//*[@href]") ではXPath指定で href 属性を持つ要素を抜き出しています。

BeautifulSoupを使ってみる

>>> from BeautifulSoup import BeautifulSoup
>>> html = '<html><head><title>test<body><h1>page title<a href="url">TEST</a></h3>'
>>> anchor = BeautifulSoup(html).findAll("a")
>>> anchor[0].get("href")
u'url'
>>> anchor[0].string
u'TEST'

BeautifulSoupは素でいい加減なHTMLを解釈できます。 いまのところXPathが使えないので findAll で<a>タグを検索します。

ここまででXMLの調理方法はOK :-) 次にpyhabuのレシピを考えます。 付属の habu.cfg をカスタマイズしてベースを作ってみます。

johzan_feed.cfg

global:
  timezone: Asia/Tokyo
  log: stdout

pipeline:
  rss_fetcher:
    - module: subscription.config
      config:
        feed:
          - http://d.hatena.ne.jp/johzan/rss2
    - module: publisher.rssfeeder
      config:
        file: "johzan_feed.rss"

余分なものをそぎ落とし subscription.config のソースに http://d.hatena.ne.jp/johzan/rss2 を、 出力のファイル名を johzan_feed.rss にしました。 これで http://d.hatena.ne.jp/johzan/rss2 をダウンロードして johzan_feed.rss というファイル名で保存するレシピの完成です。

http://d.hatena.ne.jp/johzan/rss2 には、いわゆる常山フィードだけでなく、すばらしいエントリも含まれています。 タイトルに「巡回」が含まれているいわゆる常山フィードだけを抜き出すには filter.grep を使います。

johzan_feed.cfg

global:
  timezone: Asia/Tokyo
  log: stdout

pipeline:
  rss_fetcher:
    - module: subscription.config
      config:
        feed:
          - http://d.hatena.ne.jp/johzan/rss2
    - module: filter.grep
      config:
        str:
          title: 巡回
    - module: publisher.rssfeeder
      config:
        file: "johzan_feed.rss"

さて、ここからが本番。 いわゆる常山フィードからアンカーを抜き出して個別のエントリに仕立てます。 この処理ができるpluginは、pyhabuパッケージに含まれていないので自分で作ります。 エントリからアンカーを抜き出す処理なので filter.select_anchor と命名します。

pluginの要件は現在(pyhabu 0.3)のところ、

を1つのモジュールに納めます。 何もしない最小のpluginは↓になります。

class Main(object):
    def __init__(self, config, environ):
        pass

    def execute(self, context):
        return context

def create(*argv, **kwargv):
    return Main(*argv, **kwargv)

ということで filter.select_anchorこんな感じ になりました。 ファイル名を select_anchor.py として filter ディレクトリに入れます。

レシピのYAMLは module: filter.select_anchor を差し込んで、 仕上げにtitleとlinkを追加したfeedを出力するように設定して完成です。 結果は http://michilu.com/feeds/others/johzan_junkai.xml で取得できます。

johzan_feed.cfg

global:
  timezone: Asia/Tokyo
  log: stdout

pipeline:
  rss_fetcher:
    - module: subscription.config
      config:
        feed:
          - http://d.hatena.ne.jp/johzan/rss2
    - module: filter.grep
      config:
        str:
          title: 巡回
    - module: filter.select_anchor
    - module: publisher.rssfeeder
      config:
        title: 常山日記 - 巡回
        link: http://d.hatena.ne.jp/johzan/searchdiary?word=%BD%E4%B2%F3
        file: "johzan_feed.rss"

こんな感じでpluginが増えていくとバリエーションも増えていきます。 夢が広がりんぐってやつですね。

plugin共有プロジェクト( pyhabu-plugins )を作ったので、ジョインしてがんがんコミットしてくださいまし :-)

Tue, 16 Oct 2007 03:00:01 +0900 source edit
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.1 Japan License.
View All Posts. MiCHiLU.com powered by Django ;-)