JavaでRSSの広告削除してみる(3) Removing Ads from Rss by Java

RSSから広告削除する、簡単なアプリをつくってみようかと思っています。
3回に分けて書いています。I write this in 3-posts.

第1回 JavaでRSS受信する。 Getting RSS by Java
第2回 HTMLパーサを使う。 Using HTML-parser
第3回 RSSを出力してみる。 Outputting RSS

今回は第3回めです。This is 3rd post.

————————————————————–
使っている環境

Java JDK1.6.0_35(64bit版)
Google App Engine SDK for Java 1.7.1
Eclipse IDE for Java EE Developers_ Juno (4.2)64Bit版
The Google Plugin for Eclipse, for Eclipse 3.8/4.2 (Juno)

ROME 1.0
JDOM 1.1.3
( Xerces 2.11.0 )
jsoup-1.7.2


(1)はじめに Introduction
クラスを作ってその中で「RSS読込→広告削除→RSS出力」の処理を行いたいと思います。
RSS読込・広告削除は、前回・前々回のエントリーで行ったので、今回は、まずRSS出力を試してみます。

In my Class, I would try to do entire process of “RSS-reading”, “removing-Ads”, and “RSS-outputting”.
I did “RSS-reading” and “removing-Ads” in previously post. Today, I will try to do “RSS-outputting” first.


(2)RSSの出力 Outputting RSS
SyndFeedOutput クラスのoutputString メソッドで、XMLを出力できます。
ROMEでRSSを読込んだ時のfeedを、outputString メソッドに引き渡す感じになります。
You could output XML by using outputString method of SyndFeedOutput class.
You execute outputString method with the “feed” that made by ROME .
(参考) 技術への名残り: JavaでRSSを作成(ROME利用)

        SyndFeedOutput output = new SyndFeedOutput();
        String outputRss = output.outputString(feed);

(3)コーディング Coding
CrawlRssクラスを作って、その中で処理を行うことにしました。
処理の流れはこんな感じ。
I thought that I would make “CrawlRss class” and do what’s I need.
I will show you my plan(below)

・setUrlメソッド
接続先URLをセットします。Setting URL

・getRssFeedメソッド
RSSを読込みます。このメソッドは、取得したデータ(SyndFeed型)を返します。
Reading RSS. this method will return that data as SyndFeed-type.

・doFilterメソッド
RSSのタイトルが、広告かどうかをチェックして、広告の場合は削除します。
RSSのdescriptionをチェックして、中に含まれる広告を削除します。
(広告かどうか判別する処理は、今後も増えていくため、別メソッドに書いています。
タイトルのチェックはtitleIsAdsメソッド、descriptionのチェックはhtmlParsingメソッドの中で、具体的なチェックを行っています。)

Checking “Title” of RSS-entry. and If the Title is Ads, it’s remove the RSS-entry.
Checking “description” of RSS-entry. And it’s remove Ads in the description.

・outputRssメソッド
RSSfeedデータから、RSSを出力します。String型でXMLデータを返します。
This output RSS generated from RSSfeed-data. This return RSS as XML-data.

CrawlRss.java

package rssReader;

import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.SyndFeedOutput;
import com.sun.syndication.io.XmlReader;
import com.sun.syndication.feed.synd.SyndContent; 

public class CrawlRss {
    private String url;

    /** 
     * XXX 
     *
     * @param  url  URL for getting RssFeed
     * @param  feed  RssFeed generated by ROME
     */
    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrl() {
        return this.url;
    }

    public SyndFeed getRssFeed() throws IOException  {
        SyndFeed feed = null;

        if ( this.url == null ){
            System.out.println("Parameter( url ) didn't set.");
            return null;
        }else{
            try {
                URL feedUrl = new URL(this.url);
                XmlReader reader = new XmlReader(feedUrl.openStream());
                    SyndFeedInput input = new SyndFeedInput();
                    feed = input.build(reader);
                reader.close();

            } catch (FeedException e) {
                e.printStackTrace();
            }
        }

        return feed;
    }

    public SyndFeed doFilter(SyndFeed feed){

        List<SyndEntry> entries = feed.getEntries();
        Iterator<SyndEntry> itr = entries.iterator();

        while (itr.hasNext()){
            SyndEntry entry = itr.next();

            // Removing Ads from Title
            String title = entry.getTitle();
            if ( titleIsAds(title)) {
                itr.remove();
                continue;
            }

            // Removing Ads from Desc
            SyndContent desc = entry.getDescription();

            if (desc != null){
                String html_parsed = htmlParsing(desc.getValue());
                desc.setValue(html_parsed);
            }
        }

        return feed;
    }

    public boolean titleIsAds(String title){
        if ( title.startsWith("PR:")) {
            return true;
        }else{
            return false;
        }

    }

    public String htmlParsing(String html){

        Document doc = Jsoup.parse(html, "UTF-8");
        Elements links = doc.getElementsByTag("a");

        for (Element link : links) {
            String href = link.attr("href");

            if ( href.indexOf("rss.rssad.jp/rss/ad/") != -1 ) {
                link.remove();
            }
        }

        Elements imgs = doc.getElementsByTag("img");

        for (Element img : imgs) {
            String width = img.attr("width");
            String height = img.attr("height");

            if ( width.equals("1") && height.equals("1") ) {
                img.remove();
            }
        }

        String bodies_str = doc.getElementsByTag("body").toString();
        bodies_str = bodies_str.replaceFirst("^<body>\n", "");
        bodies_str = bodies_str.replaceFirst("\n</body>$", "");
        bodies_str = bodies_str.replaceFirst("^ +", "");

        return bodies_str;
    }

    public String outputRss(SyndFeed feed) throws FeedException{
        SyndFeedOutput output = new SyndFeedOutput();
        String outputRss = output.outputString(feed);

    return outputRss;
    }
}

実際に動かす場合は、こうします。
Here is my code to use the Class.

package rssReader.test;

import java.io.IOException;

import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;

import rssReader.CrawlRss;

public class unitTest_output_XML {
    public static void main(String[] args) throws IOException, FeedException {

        CrawlRss crss = new CrawlRss();

        crss.setUrl("http://rss.rssad.jp/rss/gihyo/feed/rss2");
        // crss.setUrl("http://jp.techcrunch.com/feed/");
        // crss.setUrl("http://wired.jp/rssfeeder/");

        //System.out.println("Access to : " + crss.getUrl() + "\n\n");

        SyndFeed feed = crss.getRssFeed();

        if (feed == null){
            System.out.println("Exit");
            System.exit(-1);
        }

        feed = crss.doFilter(feed);

        String outputRss = crss.outputRss(feed);
        System.out.println(outputRss);

    }

}

こんな感じでXMLが返ってきます
That code will return these XML(below).

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>gihyo.jp:総合</title>
    <link>http://gihyo.jp/</link>
    <description>gihyo.jp(総合)の更新情報をお届けします</description>
    <language>ja-jp</language>
    <copyright>技術評論社 2013</copyright>
   :   :

    <item>
      <title>第6回 Capacity Scheduler による複数ジョブの同時実行 ── halookで始めるHadoop/HBaseトラブルシューティング</title>
      <link>http://rss.rssad.jp/rss/artclk/47ghQF72z411/6d70ced8b37632c22bd6add0ae4e4982?ul=tMUp6phKmaEl5PP2lXYGvZcEI0UboxMPKoYv1ONSRKgTtDvugPJtMP3M.QKxrTI5bkjb3.g</link>
      <description>今回は,Capacity Schedulerを使った場合について,複数ジョブの同時実行時の挙動を見てみましょう。</description>
   :   :

    </item>
    <item>
   :   :

今のところ、TechCrunch Japan、WIRED.jp、gihyo.jp のRSSfeedから広告削除できるようになっています。もうちょっと、チェックの条件を増やして、たいていのRSSに対応できるような形にできればいいなと、思っています。
This code supports removing Ads from RSS of “TechCrunch Japan”, “WIRED.jp” “gihyo.jp”.
I hope that I would add more rule to the code for removing Ads, so it could support more RSS.

それをGoogleAppEngine上で動かすようにすれば、APIとして公開できるかな。(同じようなサービスは、たくさんあるけど(笑))
And then,  I would deploy the code on GAE as an API. (There is many Service for Romoving Ads  from RSS 🙂  )

Advertisements

JavaでRSSの広告削除してみる(2) Removing Ads from Rss by Java

RSSから広告削除する、簡単なアプリをつくってみようかと思っています。
3回に分けて書いています。I write this in 3-posts.

第1回 JavaでRSS受信する。 Getting RSS by Java
第2回 HTMLパーサを使う。 Using HTML-parser
第3回 RSSを出力してみる。 Outputting RSS

今回は第2回めです。This is 2nd post.

————————————————————–
使っている環境

Java JDK1.6.0_35(64bit版)
Google App Engine SDK for Java 1.7.1
Eclipse IDE for Java EE Developers_ Juno (4.2)64Bit版
The Google Plugin for Eclipse, for Eclipse 3.8/4.2 (Juno)

jsoup-1.7.2


(1)はじめに Introduction
実際にRSS取得してみると、記事丸ごとが広告になっている場合と、要約の中に広告が埋まっている場合があります。
たとえば、タイトルが”PR:”で始まっているものは、記事全体が広告になってる。これはタイトルの文字列をチェックするだけなので取り除くのは簡単です。
I get RSS, then I found that some article are Ads, and some description contain Ads.
For example, if “Title” start with “PR:”, this articl is Ads. Checking Title is easy.

PR: 医療機関ホームページの虚偽・誇大な表現はNGです!

要約の中に広告が埋まっている場合は、以下のような形で、広告のリンクが埋まっています。
また、サイズが1×1の画像ファイルが埋め込まれていたりします。これも要らない。
This is example that a description contain “link to Ads”.  And there is “img” that it has 1x1size. this “img” have to be removed too.

<p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。
<img border="0" width="1" height="1" src="http://rss.rssad.jp/rss/artimg/47ghQF72z411/3184e1aa6c761b751f68c2613f8a3f55"/></p>
<br clear="all" /><a href="http://rss.rssad.jp/rss/ad/47ghQF72z411/pFjyc8QFo.Eh?type=1" target="_blank"><img src="http://rss.rssad.jp/rss/img/47ghQF72z411/pFjyc8QFo.Eh?type=1" border="0"/></a><br/>

これらを取り除く場合、HTMLをParseする必要があるため、HTMLパーサのライブラリを使い、不要な部分のみを取り除くことにします。
You should use HTMP-parsing-library to remove these words.


(2)jsoupのダウンロード Downloading jsoup
そもそもHTMLのパーサは、たくさんあります。There are many library.
Comparison of HTML parsers – Wikipedia, the free encyclopedia

活発に開発されていてHTML5にも対応しているものがいいと思いました。
jsoupはHTML5にも対応しており、jQuery-likeなやり方でも使えるとのことで、なかなかよさそうです。
なお、Unitテストといったことを行いたい場合は、HtmlUnitがいいみたいです。
I should use the library that is developed more active , and support  HTML5.
“jsoup” support HTML5, and jQuery-like method. I think it’s ok.
If you wish to do Unit-test , HtmlUnit would be suitable.
What are the pros and cons of the leading Java HTML parsers? – Stack Overflow
HtmlUnit vs JSoup: HTML Parsing in Java | Javalobby

今回はHTMLのparsingが目的なので、jsoupを使うことにしました。
こちらのサイトから、jsoup-1.7.2.jar をダウンロードし、Eclipseのライブラリに追加します。
I wish to use library for parsing HTML. So I chose jsoup.
you can download jsoup-1.7.2.jar in this site. And you should add it to Eclipse-library .
jsoup Java HTML Parser, with best of DOM, CSS, and jquery


(3)とりあえず読込んでみる Reading simply
テストデータとして以下の内容を、テキストファイル(testdata_html.txt)に書き込んでおき、jsoupを動かしてみました。
I tried to use jsoup. I made test-data in a text file(testdata_html.txt). I show you the test-data below.

<p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。
<img border="0" width="1" height="1" src="http://rss.rssad.jp/rss/artimg/47ghQF72z411/3184e1aa6c761b751f68c2613f8a3f55"/></p>
<br clear="all" /><a href="http://rss.rssad.jp/rss/ad/47ghQF72z411/pFjyc8QFo.Eh?type=1" target="_blank"><img src="http://rss.rssad.jp/rss/img/47ghQF72z411/pFjyc8QFo.Eh?type=1" border="0"/></a><br/>

基本的に公式ドキュメントがとてもわかりやすかったので、それを参考にしました。
I check this documents for use .
Cookbook: jsoup Java HTML parser

jsoupでテストデータを読込むと、不足している要素・タグが追加され、HTMLファイルの構成で、内部に格納されます。<html>タグや、<head>タグが追加されます。
When jsoup get test-data, jsoup make entire HTML elements. If test-data didn’t have “<html>-tag” or “<head>-tag”, jsoup would add these tags.

parsingした結果をブラウザで確認してみようと思ったので、<head>タグ内に文字コード設定を追加することにしました。
で、とりあえずテストデータを読込んで、それをそのままjsoupで出力させるコードを以下に書きます。
I think I practised jsoup and I would check the result by Browser. So I added char-setting in “<head>-tag”.
If you execute this code, it’s show you the result of “Reading RSS” and “outputting RSS-parsing-data”.

HtmlParsing.java

import java.io.File;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class HtmlParsing {
    public static void main(String[] args) throws Exception {

        File input = new File("testdata_html.txt");
        Document doc = Jsoup.parse(input, "UTF-8");

        Element head = doc.select("head").first();
        head.html("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");

        System.out.println("--- doc -----");
        System.out.println(doc + "\n");

        System.out.println("--- doc text only-----");
        System.out.println(doc.text() + "\n");

    }
}

実行結果は、こんな感じになります。
You can get this when you execute that code(above).

--- doc -----
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
 </head>
 <body>
  <p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。 <img border="0" width="1" height="1" src="http://rss.rssad.jp/rss/artimg/47ghQF72z411/3184e1aa6c761b751f68c2613f8a3f55" /></p> 
  <br clear="all" />
  <a href="http://rss.rssad.jp/rss/ad/47ghQF72z411/pFjyc8QFo.Eh?type=1" target="_blank"><img src="http://rss.rssad.jp/rss/img/47ghQF72z411/pFjyc8QFo.Eh?type=1" border="0" /></a>
  <br />
 </body>
</html>

--- doc text only-----
前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。

(4)Parsing
広告の削除と、サイズが1×1の画像ファイルの削除を行います。
I will remove Ads and img-files that has 1x1size.

<a>タグの一覧を取得し、それぞれのAttribute”href”の値を取得します。その中に”rss.rssad.jp/rss/ad/”が含まれていたら、<a>タグごと削除します。これで広告の削除ができます。
This code gets <a>-tags and each “href” Attribute. If there are the words “rss.rssad.jp/rss/ad/”, it’s remove entire <a>-tag. Then you could remove ads.

また、<img>タグの一覧を取得し、それぞれのAttribute”width”、”height”の値を取得します。width=height=1の場合、<img>タグごと削除します。
And it’s gets <img>-tags, each “width” Attribute and each “height” Attribute. If those Attribute are width=height=1, you chould remove entire <img>-tag.

ソースコードは、こんな感じになりました。
this is my code.

HtmlParsing2.java

import java.io.File;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class HtmlParsing2 {
    public static void main(String[] args) throws Exception {

        File input = new File("testdata_html.txt");
        Document doc = Jsoup.parse(input, "UTF-8");

        Element head = doc.select("head").first();
        head.html("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");

        Elements links = doc.getElementsByTag("a");

        for (Element link : links) {
            String href = link.attr("href");

            // System.out.println("href : " + href);
            // System.out.println("link.text : " + link.text());
            // System.out.println("link : " + link);

            if ( href.indexOf("rss.rssad.jp/rss/ad/") != -1 ) {
                link.remove();
            }
        }

        Elements imgs = doc.getElementsByTag("img");

        for (Element img : imgs) {
            String width = img.attr("width");
            String height = img.attr("height");
            // System.out.println("img : " + img);

            if ( width.equals("1") && height.equals("1") ) {
                img.remove();
            }
        }

        System.out.println("--- doc2 -----");
        System.out.println(doc + "\n");
        System.out.println("--- doc text only-----");
        System.out.println(doc.text() + "\n");
        System.out.println("--- body-----");
        System.out.println(doc.getElementsByTag("body") + "\n");
    }
}

実行結果は、こんな感じ。
I will how you the result.

--- doc2 -----
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
 </head>
 <body>
  <p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。 </p> 
  <br clear="all" />
  <br />
 </body>
</html>

--- doc text only-----
前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。

--- body-----
<body>
 <p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。 </p> 
 <br clear="all" />
 <br />
</body>

これで、やりたいことはできました。
Then I did.

最終的にRSSのフィードに戻すときに、<body>, </body>タグが不要になります。なので、以下のようにして、Elements型を文字列にしてから取り除くことにします。(※不要な改行と、先頭の空白文字も取り除いています。)
When you return this result to RSS-feed, <body>tag and </body>-tag didin’t need.
So I transfered type-“elements” to String, and then removed these elements . ( I removed “\n” and “blanks at the head of line”)

     :   :
        String bodies_str = doc.getElementsByTag("body").toString();
        bodies_str = bodies_str.replaceFirst("^<body>\n", "");
        bodies_str = bodies_str.replaceFirst("\n</body>$", "");
        bodies_str = bodies_str.replaceFirst("^ +", "");
     :   :

とりあえず、これで下準備がおわりました。
次回のエントリーでは、「RSS読込→広告削除→RSS出力」までつなげてみます。

In next post, I would try to do entire process of “RSS-reading”, “removing-Ads”, and “RSS-outputting”.

JavaでRSSの広告削除してみる(1) Removing Ads from Rss by Java

IT関連の情報サイトから、RSSフィードの情報収集して、その中の単語を解析・集計して、自分用のトレンドランキングをつくろうかと思った。
I come up with making “trend word list” for myself. I try to collect RSS from IT-website, analyze RSS-feed, and rank it.

ためしにRSS受信してみると、RSSフィードの中に広告が入っている場合がある。広告は削除しておきたい。Some RSS contain advertisement. I hope to remove Ads.

RSSから広告削除してくれるサービスがるんだけれども、There are some service to remove Ads from RSS.
RSS広告を削除ならRSS広告削除社

gihyo.jpのRSSの広告がうまく削除されなかった。But, that service didn’t remove Ads from “gihyo.jp”.
というわけで、自分でつくってしまおうかと思った。So I think of trying to make app.

3回に分けて書いていきます。I write this in 3-posts.

第1回 JavaでRSS受信する。 Getting RSS by Java
第2回 HTMLパーサを使う。 Using HTML-parser
第3回 RSSを出力してみる。 Outputting RSS

今回は第1回めです。This is first post.

————————————————————–
使っている環境

Java JDK1.6.0_35(64bit版)
Google App Engine SDK for Java 1.7.1
Eclipse IDE for Java EE Developers_ Juno (4.2)64Bit版
The Google Plugin for Eclipse, for Eclipse 3.8/4.2 (Juno)

ROME 1.0
JDOM 1.1.3
( Xerces 2.11.0 )


(1)はじめに Introduction
JavaのRSSライブラリには、いろいろあるみたい。
There are many library for RSS-reading.
Java や Ruby の RSS/Atom feed ライブラリなど。HTMLからRSSを自動生成……したいなぁ。 (RSS – MemoWiki)

いくつか見てみたんだけど、RSSライブラリはあんまり活発な開発がされてない雰囲気。
どうも、RSSは、昔から使われていて仕様がかたまっているため、ライブラリの改修をする必要があんまり無いっぽい。
で、なんとなく情報量の多そうな、ROMEを使うことにした。
I search RSS-library. But some RSS-library is not active.
I think that RSS-format is so old, and changeless. So, it’s no need to modify RSS-library.


(2)ROME, JDOMのダウンロード  Downloading “ROME and JDOM”
こちらのサイトから、ROMEのダウンロードを行います。僕の場合、rome-1.0.jarをダウンロードしました。
You can download ROME from this site. I downloaded rome-1.0.jar.
Home – ROME – Confluence

ROMEはJDOMと依存関係があるため、こちらのサイトからJDOMもダウンロードします。
ROME have to use with JDOM. So, you should download JDOM from thi site.
JDOM

現時点でJDOM 2.0.5が最新版でしたが、こちらを使うとROMEがうまく動きませんでした。
なので、JDOM 1.1.3を使う必要があります。ダウンロードしたファイルjdom-1.1.3.zipの中のbuildフォルダに、jdom-1.1.3.jarがあるので、これをEclipseのライブラリに追加します。
“JDOM’s latest version 2.0.5” don’t work with ROME. You should use JDOM 1.1.3.
Download jdom-1.1.3.zip, then there is jdom-1.1.3.jar in “build” folder. And add jdom-1.1.3.jar to Eclipse-library.


(3)Xercesのダウンロード Downloading Xerces
こちらは、必要に応じて使うものになります。
単体のJavaアプリとして動かす際には必要ないですが、GAE上でROMEを動かそうとすると、以下のようなエラーが出ます。

Xerces dosn’t need, if you don’t make your Apps on GAE.
But if you use ROME on GAE, you would face this error.

java.lang.IllegalStateException: JDOM could not create a SAX parser
    at com.sun.syndication.io.WireFeedInput.createSAXBuilder(WireFeedInput.java:328)
    at com.sun.syndication.io.WireFeedInput.build(WireFeedInput.java:189)
    at com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:123)
   :   :
   :   :

原因は謎。こちらのサイトによると、Xercesが必要とのこと。
I don’t know Why this error has happen. According to these site, you need Xerces.
Romeが使えない – Google グループ
Issue 1367 – googleappengine – org.apache.xerces.parsers.SAXParser not available – Google App Engine – Google Project Hosting

そのため、こちらのサイトからXercesをダウンロードします。
You can download Xerces from this site.
The Apache Xerces™ Project – xerces.apache.org

ダウンロードしたファイル Xerces-J-bin.2.11.0.tar.gz の中にある、xercesImpl.jarと、xml-apis.jar をEclipseのライブラリに追加します。
Download Xerces-J-bin.2.11.0.tar.gz. In this file, you can get xercesImpl.jar and xml-apis.jar. Then you need to add these Jar-files into Eclipse-library.


(4)コーディング Coding
こちらのサイトを参考にしました。
This site will help you.
JavaのRSSライブラリ、ROMEを使ってみる
RSS・Atomフィードのためのライブラリ”ROME” – argius note
Kazuhiro’s Weblog: Javaで手軽にフィード(RSS、Atom)を扱うライブラリ 「ROME」

RSS取得時のコードは以下のような書き方になります。
You can get RSS with this code.

        String url = "http://jp.techcrunch.com/feed/";

        URL feedUrl = new URL(url);
        XmlReader reader = new XmlReader(feedUrl.openStream());
            SyndFeedInput input = new SyndFeedInput();
            SyndFeed feed = input.build(reader);
        reader.close();

上記では取得したデータが、feedの中に格納されています。
feed.getTitle()といった形で、個々のデータが取得できます。
RSSの1つ1つの記事は、feed.getEntries()でまとめて取得できます。List形式のデータになっています。

That code will give you RSS-data in  a variable “feed”.
You can get each a RSS-element using the method “feed.getTitle()”.
And you can get a RSS-entry using the method “feed.getEntries()”.

とりあえず、取得したデータをすべて表示してみることにしました。最終的なソースコードを以下にまとめて記載します。
I could show you each elements in RSS., If you use this code.

RomeSample3.java

import java.net.URL;
import java.util.List;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class RomeSample3 {
    public static void main(String[] args) throws Exception {
        // String url = "http://rss.rssad.jp/rss/gihyo/feed/rss2";

        // String url = "http://rss.dailynews.yahoo.co.jp/fc/rss.xml";
        String url = "http://jp.techcrunch.com/feed/";
        // String url = "http://wired.jp/rssfeeder/";

        URL feedUrl = new URL(url);
        XmlReader reader = new XmlReader(feedUrl.openStream());
            SyndFeedInput input = new SyndFeedInput();
            SyndFeed feed = input.build(reader);
        reader.close();

        // ###########################################################
        System.out.println("----- Site Infomation ----------------------------------");
        System.out.println("SITE author : " + feed.getAuthor());
        System.out.println("SITE authors : " + feed.getAuthors());
        System.out.println("SITE categories : " + feed.getCategories());
        System.out.println("SITE contributors : " + feed.getContributors());
        System.out.println("SITE Copyright : " + feed.getCopyright());
        System.out.println("SITE description : " + feed.getDescription());
        System.out.println("SITE DescriptionEx : " + feed.getDescriptionEx());
        System.out.println("SITE encoding : " + feed.getEncoding());
        System.out.println("SITE feedType : " + feed.getFeedType());
        System.out.println("SITE ForeignMarkup : " + feed.getForeignMarkup());
        System.out.println("SITE image : " + feed.getImage());
        System.out.println("SITE language : " + feed.getLanguage());
        System.out.println("SITE link : " + feed.getLink());
        System.out.println("SITE links : " + feed.getLinks());
        // System.out.println("SITE Module : " + feed.getModule(url));
        // System.out.println("SITE Modules : " + feed.getModules());
        System.out.println("SITE getPublishedDate : " + feed.getPublishedDate());
        System.out.println("SITE getSupportedFeedTypes : " + feed.getSupportedFeedTypes());
        System.out.println("SITE title : " + feed.getTitle());
        System.out.println("SITE getTitleEx : " + feed.getTitleEx());
        System.out.println("SITE uri : " + feed.getUri());

        // ###########################################################
        List<SyndEntry> entries = feed.getEntries();

        Integer i = 1;
        for (SyndEntry entry : entries) {
            System.out.println("----- Entries No." + i + "----------------------------------");
            System.out.println("ENTRY Author : " + entry.getAuthor());
            System.out.println("ENTRY Authors : " + entry.getAuthors());
            System.out.println("ENTRY Categories : " + entry.getCategories());
            System.out.println("ENTRY Contents : " + entry.getContents());
            System.out.println("ENTRY Contributors : " + entry.getContributors());
            System.out.println("ENTRY Description : " + entry.getDescription());
            System.out.println("ENTRY Enclosures : " + entry.getEnclosures());
            System.out.println("ENTRY ForeignMarkup : " + entry.getForeignMarkup());
            System.out.println("ENTRY Link : " + entry.getLink());
            System.out.println("ENTRY Links : " + entry.getLinks());
            // System.out.println("ENTRY Module : " + entry.getModule(url));
            // System.out.println("ENTRY Modules : " + entry.getModules());
            System.out.println("ENTRY PublishedDate : " + entry.getPublishedDate());
            System.out.println("ENTRY Source : " + entry.getSource());
            System.out.println("ENTRY Title : " + entry.getTitle());
            System.out.println("ENTRY TitleEx : " + entry.getTitleEx());
            System.out.println("ENTRY UpdatedDate : " + entry.getUpdatedDate());
            System.out.println("ENTRY Uri : " + entry.getUri());
            System.out.println("ENTRY WireEntry : " + entry.getWireEntry());
            System.out.println("");

            i = i + 1;
        }
    }
}

これで、RSSの受信はできました。I could get RSS.

ほしい情報は、記事のタイトルと要約の部分になります。ソース上では以下の部分。
Title and Descriptin are important for me. I can get those using this method .

entry.getTitle()
entry.getDescription()

実際にRSS取得してみると、記事丸ごとが広告になっている場合と、要約の中に広告が埋まっている場合があります。
タイトルが”PR:”で始まっているものは、記事全体が広告になってる。これはタイトルの文字列をチェックするだけなので取り除くのは簡単です。
要約の中に広告が埋まっている場合は、以下のような形で、広告のリンクが埋まっています。

I got RSS-feed, then I found that there is some Ads in RSS. Some entry are ads, and some RSS-description has ads.
If “Title” start with “PR:” , RSS-entry is a advertisement. It’s easy to check “Title”.
But if RSS-description had ads, it’s difficult to remove ads.
This is sample that there are “link to ads” in description.

<p>前回紹介したように,gmtpに文字コード回りのパッチをあてることで,無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら,あれこれ使っているとgmtpの欠点も目についてきました。
<img border="0" width="1" height="1" src="http://rss.rssad.jp/rss/artimg/47ghQF72z411/3184e1aa6c761b751f68c2613f8a3f55"/></p>
<br clear="all" /><a href="http://rss.rssad.jp/rss/ad/47ghQF72z411/pFjyc8QFo.Eh?type=1" target="_blank"><img src="http://rss.rssad.jp/rss/img/47ghQF72z411/pFjyc8QFo.Eh?type=1" border="0"/></a><br/>

この場合HTMLをParseする必要があるため、HTMLパーサのライブラリを使い、不要な部分のみを取り除くことにします。ここから先は、次回のエントリーで。
In this case, I have to parse HTML. So I will use HTML-parsing-library. And I will remove the link of ads.
I will show you that in next post.