Node.js
スクレイピング
casperJs
テスト自動化
cheerio-httpcli

nodeでスクレイピングをしたのでライブラリ「CasperJS」と「cheerio-httpcli」の紹介

フロムスクラッチ Advent Calendar 2017 の19日目の記事です。

はじめに

WEBサイトの情報を定期的に取得したいときってありますよね。
しかも、広大なサイト内の情報を定期的に、、、指定文字を検索するとか、色々とWEBサイトを巡回して自動化したいという要望に答えるべく、プログラムを書きます。

WEBサイトからデータ取得する時に必要な技術要素は、「スクレイピング」ですね。

スクレイピングとは

ウェブスクレイピング(Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー(Web crawler) あるいはウェブ・スパイダー(Web spider)とも呼ばれる。
ウェブスクレイピング – Wikipediaより

強力なクローリング・スクレイピングフレームワークのScrapy(python)など、有名ですが、今回は気軽にサクサク作れるnodeで作ってみました。

目標は取得したいURLは別で用意しているので、そこからスタート!

nodeでスクレイピングをしたのでライブラリの紹介

今回のターゲットは「CasperJS」と「cheerio-httpcli

この2つを簡単に紹介

『cheerio-httpcli』の説明

cheerioはHTMLパーサに jQuery API のサブセットを実装したものです。
DOM APIはありません。必ずjQueryの関数を使う必要があります。
→静的なHTMLをベースに処理するモジュールなのでSPAなどクライアントサイドのJavaScriptによってコンテンツを取得/変更するタイプのWEBページには対応していません。

↓github
https://github.com/ktty1220/cheerio-httpcli

『CasperJS』の説明

phantomjs という Javascript で動かせるヘッドレスブラウザと casperjs というユーティリティを使って動かすという感じです。
PhantomJS のレンダリングエンジンには Webkit が使われています
CasperJS は、その PhantomJS をより手軽に使えるようにするライブラリです
casperJSはphantomJSがないと動きません。

↓github
https://github.com/casperjs/casperjs
↓公式サイト
http://casperjs.org/
↓公式APIドキメント
http://docs.casperjs.org/en/latest/modules/index.html

この2つを選んだ理由と使い分け

『cheerio-httpcli』を選んだ理由

jQueryに慣れている場合は、学習コストが低く済むハズ。

今まで使っていた『jQuery』をサーバーでサイドで使えるとは、使ってみるしか無いでしょ。
確実に、工数削減に繋がったハズ

プロキシサーバー経由でアクセスの設定標準で用意されている

AWSでサーバーを用意すると、そのIP帯からのアクセスをブロックしているサイトがあるので、プロキシを経由するなどの対策が取りやすいので、この対応が出来るライブラリを選出

User-Agentを手動で設定出来る

スマートフォンサイト、PCTサイト、タブレットサイトで表示形態が異なる事があるので、UAを個別にしてい出来ると確認がし易いので、運用上ここも重要なポイント

受信するデータの限界量を数値(バイト数)で指定出来る

このライブラリの目的はHTMLをサックっと取得して、さくっと抽出するという軽い処理を並行で実施したいので、大きいサイズのページとかはエラーでスキップしたいので、これもポイント高い!

同期処理、非同期処理用の関数が用意されている

今回は使わなかったが、同期処理と非同期処理の関数が用意されているので、対象ページに寄って同期・非同期を分けるなどがし易くなるハズ
※ここは将来の拡張性の話

『CasperJS』の説明

phantomjs という Javascript で動かせるヘッドレスブラウザと casperjs というユーティリティを使って動かすという使い方が多いです。

PhantomJSを使ってブラウザなしでWebページを表示・実行できる

『PhantomJS』は、

  • Webkitベースのヘッドレスで高速なブラウザ
  • ヘッドレスとはGUIを持たないという意味で、完全にCUIでのみ動作
  • CanvasやSVGなどもサポートされていて、画像を出力する事も可能

なので、ajaxを使った表示にも対応出来るのでクライアントサイドのJavaScriptによってコンテンツを取得/変更するタイプのWEBページにも対応ができる

PhantomJSを使ってスクリーンキャプチャを自動化が可能

PhantomJSはコマンドラインから実行するWEBブラウザで、ヘッドレスブラウザ(GUIがないコマンドライン用のブラウザ)なので、レンダリングした後のキャプチャを撮ることができる

エンジンを PhantomJS 以外に出来る

  • phantomjs : Chrome系エンジン
  • slimerjs : Firefox系エンジン
  • triflejs : IE系エンジン

CasperJSはCoffeeScriptも実行可能

※ここは将来の拡張性の話

導入&サンプル

cheerio-httpcli導入編

sudo npm install cheerio-httpcli

一応上記のコマンドについて補足すると、cheerio-httpcliをグローバルにインストールしています。

cheerio-httpcliサンプル

cheerio.js
var client = require('cheerio-httpcli');
var TARGET ="https://bdash-marketing.com/";

client.fetch(TARGET , (err, $, res) => {
    const result = [];
    $('.normal_list').each(function (id, el) {
        const month = $(this).find('#home-section-header').text();

        $(this).find('li').each(function (id, el) {
            result.push(month + $(this).text().replace(/\r?\n?/g, ''));
        });
    });

    console.log(result.join('\n'));
});

CasperJS導入編

CasperJSのインストール 公式サイトからダウンロードできます。

sudo npm install -g phantomjs
sudo npm install -g casperjs

一応上記のコマンドについて補足すると、PhantomJSとCasperJSをグローバルにインストールしています。

CasperJS サンプル

gethtml.js を用意

gethtml.js
var casper = require('casper').create();
var fs = require('fs');
var $  = require('jquery');
var FILE_NAME = "output.html";
var TARGET ="https://bdash-marketing.com/";
var outs =[];

casper.start(TARGET, function(){
  // id="home-section-header"のコンテンツを取得する
  var t = this.getHTML("#home-section-header");
  // jqueryオブジェクト化してリンクを取得する
  $(t).find("a").each(function(){
      outs.push($(this).prop('outerHTML')+"\r\n");
  });
});

casper.then(function(){
  // 取得したリンクリストをファイル出力
  fs.write(FILE_NAME, outs.join(""));
});

casper.run();

casperjs gethtml.js で実行
output.html を確認する