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”.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s