フロムスクラッチ 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サンプル
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
を用意
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
を確認する