Edited at

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

More than 1 year has passed since last update.

フロムスクラッチ 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 を確認する