連載
» 2007年08月09日 00時00分 公開

そろそろブログ+RSSアプリでも作ってみませんか?小山博史のJavaを楽しむ(7)(3/3 ページ)

[小山博史,ガリレオ]
前のページへ 1|2|3       

RSSフィードをブログに投稿をするには?

 さて、無事にRollerも稼働させることができたので、アカウント名「guest」、パスワード「guestpass」というアカウントを作成し、「News Collection」というブログを「http://localhost:8080/roller/nc」というURIで作成しました。

仕事で使える便利なブログにしよう

 ここへ、IT系のニュースで気になったものをピックアップしてブログを書くと想定します。このとき、時間がある日は、IT系のニュースをRSSリーダでチェックして、興味のあるページを確認してからブログ記事を執筆するということもできますが、忙しいときは、そこまで作業をしている時間がないこともあります。

 そんなときには、プログラムで自動的に注目に値するリンク集が作成できて、それがブログへ下書きの状態で用意されていれば便利だと思いませんか? そうなっていれば、その下書きのエントリを、注目リンク集としてブログへ簡単にできるからです。

 もちろん、自分が本当に興味のあるタイトルだけ残すといった作業は必要ですが、全部手作業で行う必要はないので、数分間のチェック程度で済ませることができるはずです。IT系のニュースサイトはRSS/Atomといったフィードを提供していることが多いので、それらを使えば、このような処理は可能です。

 情報の共有や流通を考えると、こういったフィードを利用して情報を収集し再利用するということは、すでに行われていますし、これからはこういった処理は普通にプログラミングされていくことでしょう。

Romeを使う

 ということで、java.netで公開されていて、RSS/Atomフィードを扱うために作成されたRomeというオープンソースのライブラリを使って、実現してみました。Rome FetcherRome ProponoJDOMも必要です。

図8 Romeのプロジェクトサイト 図8 Romeのプロジェクトサイト

 最初に、次のような、RSS/AtomフィードのURIと、チェックしたいキーワードをペアとして持つTargetInfoクラスを用意します。

class TargetInfo {
    private String uri;
    private String key;
 
    public TargetInfo(String uri, String key) {
        this.uri = uri;
        this.key = key;
    }
    public String getUri() { return uri; }
    public String getKey() { return key; }
} 
TargetInfo.java

 TargetInfoクラスを使って、URIで指定したフィードより、キーワードを含むタイトルとカテゴリの記事のリストを取得するRssFetcherクラスを用意します。FeedFetcherクラス、SyndEntryクラスといったものは、Romeに含まれるcom.sun.syndication.fetcherパッケージやcom.sun.syndication.feed.syndパッケージのクラスです。RssFetcherの例を見れば分かるように、非常に簡単にフィードを扱うことができます。

class RssFetcher {
    private List<SyndEntry> targetEntries =new ArrayList<SyndEntry>();
    private List<TargetInfo> targetList = new ArrayList<TargetInfo>();
 
    public RssFetcher() {
        targetList.add(new TargetInfo(
            "http://www.atmarkit.co.jp/rss/rss.xml","Java"));
        targetList.add(new TargetInfo(
            "http://www.atmarkit.co.jp/rss/rss.xml","Linux"));
    }
    public List<SyndEntry> getEntries() {
        return targetEntries;
    }
 
    public void getFeed() throws Exception {
        FeedFetcher fetcher = new HttpURLFeedFetcher();
 
        for (TargetInfo info:targetList) {
            URL feedUrl = new URL(info.getUri());
            SyndFeed feed = fetcher.retrieveFeed(feedUrl);
            List entries = feed.getEntries();
 
            for (int i = 0; i < entries.size(); i++) {
                SyndEntry e = (SyndEntry) entries.get(i);
 
                for (Object o: e.getCategories()) {
                    SyndCategory category = (SyndCategory)o;
                    String categoryName = category.getName();
                    boolean isTarget = false;
                    isTarget 
                        =  (-1 !=categoryName.indexOf(info.getKey())) 
                        || (-1 !=e.getTitle().indexOf(info.getKey()));
 
                    if (isTarget) {
                        targetEntries.add(e);
                    }
                }
            }
        }
    }
} 
RssFetcher.java

 RssFetcherで取得したエントリの一覧をブログへ投稿するBlogClientクラスは、次のようになります。Rome Proponoに含まれるcom.sun.syndication.propono.blogclientパッケージを使うと、これも簡単に実装できます。Roller側ではブログの設定で「Blogger API を使用できるようにしますか?」をチェックして投稿可能にしておく必要があります。

class BlogClient {
    private String username = "guest";
    private String password = "guestpass";
    private String type = "metaweblog"; // or "atom"
    public BlogClient() {}
 
    public void postEntry(List<SyndEntry> targetEntries) 
    throws BlogClientException {
        String title    = "["+new Date()+"] 注目の記事";
        String htmltext = createText(targetEntries);
        String uri
            = "http://localhost:8080/roller/roller-services/xmlrpc";
 
        //String uri      = "http://localhost/wordpress/xmlrpc.php";
        BlogConnection conn = 
BlogConnectionFactory.getBlogConnection(
                                    type, uri, username, password);
        Blog blog = (Blog)conn.getBlogs().get(0);
        BlogEntry entry = blog.newEntry();
 
        //BlogEntry entry = blog.getCollection().newEntry();
        entry.setTitle(title);
        entry.setContent(new Content(htmltext));
        entry.setDraft(true);
        entry.save();
    }
 
    private String createText(List<SyndEntry> targetEntries) {
        // 略
        return sb.toString();
    }
} 
BlogClient.java

RSSを取得してブログ投稿する流れ

 処理の流れは単純で、ブログシステムへログイン、対象ブログを取得、新しいエントリを作成して対象ブログへ下書きとして投稿、というものです。対象ブログは、ブログシステムからブログ一覧を取得した後にブログ名から取得することもできますが、ここではサンプルなので、単純に最初のブログを取ってきています。

 なお、新しいエントリを作成する処理において、「BlogEntry entry = blog.newEntry();」の部分は非推奨の書き方で、「BlogEntry entry = blog.getCollection().newEntry();」とする方がよいようです。ただし、今回使用したバージョンのRome Proponoでは、そうするとうまく動作しなかったので、非推奨の方法を使っています。サンプルプログラムの完全な例は最後に記載しておきます。

 このプログラムでは、typeとして「metaweblog」を使っていますが、投稿する先のブログシステムがAtomを使える場合にはtypeに「atom」を指定します。

投稿先URIを知るには?

 なお、Rollerの場合の投稿先URIは「http://localhost:8080/roller/roller-services/xmlrpc」を見れば分かるように、「/roller/roller-service/xmlrpc」です。

 これはブログシステムによって異なります。WordPressでは、「http://localhost/wordpress/」が対象となるブログのURIだとすると、「/wordpress/xmlrpc.php」のようになります。

 ちなみに、この投稿先URIは、次のようにして知ることができます。ブログのエントリをWebブラウザで開いてからHTMLソースコードを見ると、「」のように、編集用の情報が書かれたXMLファイルのURIが分かります。このURIを開いてXMLファイルを取得してから、そのファイルを開くと対応しているAPIとエントリポイントが分かるのです。

<?xml version="1.0" encoding="utf-8"?>
<rsd version="1.0">
  <service>
    <engineName>Roller Weblogger</engineName>
    <engineLink>http://www.rollerweblogger.org/</engineLink>
    <homePageLink>http://localhost:8080/roller/nc</homePageLink>
    <apis>
      <api name="blogger" preferred="false"
         apiLink="http://localhost:8080/roller/roller-services/xmlrpc"
         blogID="nc"/> 
      <api name="metaWeblog" preferred="true"
         apiLink="http://localhost:8080/roller/roller-services/xmlrpc"
         blogID="nc"/>
    </apis>
  </service>
</rsd> 
編集用の情報が書かれたXMLファイル

ブログ+RSSプログラムを実行すると?

 プログラムを実行すると、図9のように下書きの状態でブログへエントリが投稿されます。これを公開すると、図10のようにブログで表示されます。

図9 ブログ+RSSプログラムの実行画面 図9 ブログ+RSSプログラムの実行画面
図10 ブログで表示された後の画面 図10 ブログで表示された後の画面

ブログシステムをいろいろとカスタマイズしてみよう

 たったこれだけのプログラムで、フィードから情報を抽出してブログへ投稿するということが実現できてしまいました。

 実際には、フィードには十分な情報がないことが多く、よりきめ細かい抽出をするためには、フィードの情報から実際のコンテンツを取得して、そこから判定をするといった処理が必要になってくるはずですが、基本となる処理を実現できたので、いろいろと応用できそうです。

 単純なブログシステムを用意して運用するだけでも十分意味がありますが、せっかく用意するなら、ちょっとカスタマイズをしたり、工夫をしてより有用なシステムを構築できると、楽しいのではないでしょうか。今回のサンプルでは「連絡、報告、コメントの募集、といった情報の共有と流通を改善する」ということを直接的に解決するものとはなっていませんが、ちょっとした工夫で実現できる部分もあるはずです。

 Rollerの環境を用意するのに少々時間がかかりますが、ブログを使った応用システム開発への要望は強くなってくると思います。ぜひ、試してみてください。

 今回のサンプルソースはここからダウンロードできます。

@IT関連リンク

社内ブログはナレッジマネジメントとして機能するか
ネットワークコラム:ものになるモノ、ならないモノ(1) ナレッジマネジメントツールとしての「社内ブログ」サービスが増えてきた。効力を高める仕組みについて考えてみよう
Master of IP Network」フォーラム 2005/6/7

社内ブログを導入しよう
連載:運用管理者のための知恵袋(16) 運用管理者に向けたコラムの最終回として、社内ブログを導入すべき理由や運用上の注意点を解説する
情報マネジメント > インフラストラクチャ 2007/6/20

ブログで育てる自分戦略
コラム:自分戦略を考えるヒント(35) ブログは書くべきだと筆者は語る。自分戦略にも役立つブログとは、何をテーマに、どのように書けばいいのか。それを紹介しよう
自分戦略研究所 > 自分戦略研究室 2006/11/30

Windowsでイントラ・ブログを構築する(前編)
Windows:運用 企業での新しい情報共有手段として、ブログが急速に普及しつつある。Windows+無償ブログソフトを利用して、イントラネットにブログサーバを構築してみよう
Windows Server Insider」フォーラム 2005/6/23

Windowsでイントラ・ブログを構築する(後編)
Windows:運用 前編でご紹介したCommunity Serverに引き続き、後編では商用利用を含めて無償利用が可能なDotNetNukeを用いたイントラブログの構築法を解説する
Windows Server Insider」フォーラム 2005/8/11

利用客のナレッジを取り込むポータルブログ[阪急電鉄]
連載:ビジネスWeb 2.0事例(1) ブログもWeb 2.0の考え方もなかった時代に、阪急電鉄は自社のWebページで、利用客による利用客のためのコンテンツを開始した
情報マネジメント > インフラストラクチャ 2006/5/20

筆者プロフィール

小山博史(こやま ひろし)

Webシステムの運用と開発、コンピュータと教育の研究に従事する傍ら、オープンソースソフトウェア、Java技術の普及のための活動を行っている。Ja-Jakartaプロジェクトへ参加し、コミッタの一員として活動を支えている。また、長野県の地域コミュニティである、SSS(G)bugs(J)の活動へも参加している。



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。