2016年3月16日水曜日

Node.jsのスクレイピングモジュールcheerio-httpcliがとても便利

こんにちは。エンジニアのKです。

先日、自社サイト上にて静的HTMLで公開している100ページ近くあるコンテンツを、
改めてDBに登録したいという要望がありました。

幸い、対象のページはHTML的に似た構造をしていたので、スクレイピングで上手いことデータを抽出できないかと調べていたところ、
Node.jsで動く「cheerio-httpcli」を見つけ、とても便利だったので紹介したいと思います。

作者様のGitHubとか
GitHub - ktty1220/cheerio-httpcli
Node.js用のスクレイピングモジュール「cheerio-httpcli」の紹介

スクレイピングって?


ひとことで言うと、「ウェブサイトのHTMLを取得して、その中から必要な情報を取り出す」処理になるでしょうか。
再帰的にリンクを辿って行く場合、大量のリクエストが飛んでしまいますので、リクエスト間にインターバルを設けるなどしてDoS攻撃にならないようにしましょう。
また、取得したコンテンツには著作権がありますので取り扱いに注意しましょう。

cheerio-httpcliをインストール

今回はまっさらなCentOS 6にてインストールしていきたいと思います。
cheerio-httpcliはnpmでインストールするのが取ってり早いですが、
npmを使うためにはnodejsが必要となり、
さらにnodejsをインストールするためにはepelリポジトリをyumに追加する必要があります。
順番にやっていきます。

epelリポジトリ追加

$ yum install epel-release

nodejs/npmインストール

$ yum install nodejs npm --enablerepo=epel

# 確認
$ node -v                                                                        
v0.10.36

cheerio-httpcliインストール

$ npm install cheerio-httpcli


これでインストール完了です。

スクレイピングのサンプル

抽出したデータで特に何をするというわけではありませんが、サンプルとしてYahooトップページのトピックスの見出しとURLを取得してみたいと思います。

// test.js
var client = require('cheerio-httpcli');

client.fetch('http://www.yahoo.co.jp')
.then(function (result) {
    var $ = result.$;
    $('.topicsindex .emphasis a').each(function (idx) {
        var title = $(this).contents().filter(function () {return this.nodeType === 3;}).text(),
            url = $(this).attr('href');

        console.log(title + ',' + url);
    });
})
.catch(function (error) {
    console.log(error);
});

実行結果がこちら

$ node test.js
大阪女児焼死 母ら無罪確定へ,http://rdsig.yahoo.co.jp/...
原子力規制委 朝日記事を批判,http://rdsig.yahoo.co.jp/...
北 米学生に15年の労働教化刑,http://rdsig.yahoo.co.jp/...
6人殺害 妻と娘失った夫苦悩,http://rdsig.yahoo.co.jp/...
「尿鑑定不採用」で無罪判決,http://rdsig.yahoo.co.jp/...
福山雅治 健さん映画で主演,http://rdsig.yahoo.co.jp/...
内海また炎上 開幕ローテ絶望,http://rdsig.yahoo.co.jp/...
足に30cmボルト 新城幸也の今,http://rdsig.yahoo.co.jp/...

たったこれだけのコードで簡単なスクレイピングができてしまいます。便利ですね。
result.$にはjQueryオブジェクトが渡されるので、セレクタによるDOM操作も簡単に行えます。便利ですね。

githubのドキュメントにもまだまだ便利そうなAPIがありそうなので、色々試してみたいですね。



1 件のコメント: