2015年11月11日水曜日

OpenCV3.0.0のインストール

このエントリーをはてなブックマークに追加

昔、1.x時代に少し触ったことがあったのだけど、今は3.0にまでなってると知ったのでもう一回触ってみたくてインストールしてみた。

OpenCVのインストールに必要なパッケージのインストール


まずはソースをダウンロードして解凍するとこまでは省略。

こっからcmakeしていくわけだけど、画像や動画周りのライブラリがあからさまに足りなさそう。なので、OpenCVのドキュメントを見ながら潰していくことにした。
http://docs.opencv.org/3.0-last-rst/doc/tutorials/introduction/linux_install/linux_install.html?highlight=install

Ubuntuベースで書かれているので少し困る。僕が入れようとしているのはFedoraだ。apt-getではなくdnfなのだ。すでに心が折れそうなのだが読み解いて、足らない時は考える方向にした。

書かれているのは
[compiler] sudo apt-get install build-essential
[required] sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
[optional] sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
といった感じ。すでにffmpegがないのが気がかりな点だったのだが、
ffmpeg or libav development packages: libavcodec-dev, libavformat-dev, libswscale-dev
とあるので、ライブラリかffmpegかが入っていればよさそうだ。

少し調べてみよう。

ちなみにRPM Fusionのリポジトリは追加済み。パッケージ調べてみてこれでいけるんじゃないかと踏んだ。
# dnf install ffmpeg-devel ffmpeg gtk2-devel pkgconfig python-devel numpy openjpeg-devel libpng-devel libtiff-devel jasper-devel tbb tbb-devel libdc1394-devel libdc1394
メタデータの期限切れの確認は、0:16:32 前の Wed Nov 11 03:30:28 2015 に実施しました。
Package pkgconfig-1:0.28-9.fc23.x86_64 is already installed, skipping.
依存性が解決されました。
========================================================================================================================
 パッケージ                アーキテクチャ
                                       バージョン                             リポジトリ                           容量
========================================================================================================================
インストール中:
 SDL                       x86_64      1.2.15-20.fc23                         updates                             213 k
 atk-devel                 x86_64      2.18.0-1.fc23                          fedora                              185 k
 atlas                     x86_64      3.10.2-6.fc23                          fedora                              5.7 M
 cairo-devel               x86_64      1.14.2-2.fc23                          fedora                              354 k
 expat-devel               x86_64      2.1.0-12.fc23                          fedora                               61 k
 ffmpeg                    x86_64      2.8.1-1.fc23                           rpmfusion-free-updates-testing      1.3 M
 ffmpeg-devel              x86_64      2.8.1-1.fc23                           rpmfusion-free-updates-testing      679 k
 ffmpeg-libs               x86_64      2.8.1-1.fc23                           rpmfusion-free-updates-testing      5.5 M
 fontconfig-devel          x86_64      2.11.94-4.fc23                         fedora                              137 k
 freetype-devel            x86_64      2.6.0-3.fc23                           fedora                              378 k
 fribidi                   x86_64      0.19.6-5.fc23                          fedora                               69 k
 gdk-pixbuf2-devel         x86_64      2.32.1-1.fc23                          fedora                              217 k
 gl-manpages               noarch      1.1-10.20140424.fc23                   fedora                              1.0 M
 glib2-devel               x86_64      2.46.1-2.fc23                          fedora                              436 k
 graphite2-devel           x86_64      1.2.4-5.fc23                           fedora                               41 k
 gtk2-devel                x86_64      2.24.28-2.fc23                         fedora                              2.9 M
 harfbuzz-devel            x86_64      1.0.6-1.fc23                           updates                             122 k
 jasper-devel              x86_64      1.900.1-31.fc23                        fedora                              379 k
 lame-libs                 x86_64      3.99.5-5.fc23                          rpmfusion-free-updates-testing      345 k
 libX11-devel              x86_64      1.6.3-2.fc23                           fedora                              984 k
 libXau-devel              x86_64      1.0.8-5.fc23                           fedora                               19 k
 libXcomposite-devel       x86_64      0.4.4-7.fc23                           fedora                               21 k
 libXcursor-devel          x86_64      1.1.14-4.fc23                          fedora                               27 k
 libXdamage-devel          x86_64      1.1.4-7.fc23                           fedora                               14 k
 libXext-devel             x86_64      1.3.3-3.fc23                           fedora                               79 k
 libXfixes-devel           x86_64      5.0.1-5.fc23                           fedora                               17 k
 libXft-devel              x86_64      2.3.2-3.fc23                           fedora                               24 k
 libXi-devel               x86_64      1.7.4-3.fc23                           fedora                              109 k
 libXinerama-devel         x86_64      1.1.3-5.fc23                           fedora                               18 k
 libXrandr-devel           x86_64      1.5.0-2.fc23                           fedora                               25 k
 libXrender-devel          x86_64      0.9.9-2.fc23                           fedora                               21 k
 libXxf86vm-devel          x86_64      1.1.4-2.fc23                           fedora                               23 k
 libass                    x86_64      0.12.1-2.fc23                          fedora                               85 k
 libavdevice               x86_64      2.8.1-1.fc23                           rpmfusion-free-updates-testing       76 k
 libdc1394                 x86_64      2.2.2-4.fc23                           fedora                              123 k
 libdc1394-devel           x86_64      2.2.2-4.fc23                           fedora                               57 k
 libdrm-devel              x86_64      2.4.65-1.fc23                          fedora                              111 k
 libgfortran               x86_64      5.1.1-4.fc23                           fedora                              285 k
 libicu-devel              x86_64      54.1-5.fc23                            fedora                              741 k
 libjpeg-turbo-devel       x86_64      1.4.1-2.fc23                           fedora                              104 k
 libpng-devel              x86_64      2:1.6.17-2.fc23                        fedora                              310 k
 libquadmath               x86_64      5.1.1-4.fc23                           fedora                              173 k
 libraw1394-devel          x86_64      2.1.0-6.fc23                           fedora                               44 k
 libtiff-devel             x86_64      4.0.4-1.fc23                           fedora                              487 k
 libva                     x86_64      1.6.1-1.fc23                           fedora                               83 k
 libxcb-devel              x86_64      1.11.1-1.fc23                          updates                             1.1 M
 libxshmfence-devel        x86_64      1.2-2.fc23                             fedora                              9.6 k
 mesa-libEGL-devel         x86_64      11.0.3-1.20151012.fc23                 fedora                               42 k
 mesa-libGL-devel          x86_64      11.0.3-1.20151012.fc23                 fedora                              163 k
 numpy                     x86_64      1:1.9.2-2.fc23                         fedora                              3.0 M
 openal-soft               x86_64      1.16.0-7.fc23                          fedora                              290 k
 opencv-core               x86_64      2.4.11-5.fc23                          fedora                              1.8 M
 openjpeg                  x86_64      1.5.1-15.fc23                          fedora                              189 k
 openjpeg-devel            x86_64      1.5.1-15.fc23                          fedora                              376 k
 openjpeg-libs             x86_64      1.5.1-15.fc23                          fedora                               89 k
 pango-devel               x86_64      1.38.1-1.fc23                          fedora                              324 k
 pixman-devel              x86_64      0.33.4-1.fc23                          updates                              18 k
 python-devel              x86_64      2.7.10-8.fc23                          fedora                              397 k
 python-macros             noarch      2.7.10-8.fc23                          fedora                               61 k
 python-nose               noarch      1.3.7-4.fc23                           fedora                              280 k
 schroedinger              x86_64      1.0.11-9.fc23                          fedora                              317 k
 tbb                       x86_64      4.3-3.20141204.fc23                    fedora                              140 k
 tbb-devel                 x86_64      4.3-3.20141204.fc23                    fedora                              259 k
 x264-libs                 x86_64      0.148-1.20151020gita0cd7d3.fc23        rpmfusion-free-updates-testing      590 k
 x265-libs                 x86_64      1.8-1.fc23                             rpmfusion-free-updates-testing      528 k
 xorg-x11-proto-devel      noarch      7.7-16.fc23                            fedora                              287 k
 xvidcore                  x86_64      1.3.4-2.fc23                           rpmfusion-free-updates-testing      266 k
 zlib-devel                x86_64      1.2.8-9.fc23                           fedora                               55 k

トランザクションの要約
========================================================================================================================
インストール  68 Packages

総ダウンロード容量: 34 M
インストール済み容量: 139 M

OpenCVのインストール

OpenCVのconfigureをccmakeで行う。インストール先は/usr/local/opencvとして、python, javaにも対応しておく。あとexampleも入れておきたい。
# cd /usr/local/src/opencv-3.0.0/
# mkdir build
# cd build/
# ccmake ..

PackageKit-Qt5-develも必要だったのと、python3-develpython3-numpyplibv4l-develpmesa-libGL-develmesa-libGLU-develも追加しておいた。

またJAVA用にantも探しているぽかったのでインストールしておいた。

# wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/ant/binaries/apache-ant-1.9.6-bin.tar.gz
# tar -xvzf apache-ant-1.9.6-bin.tar.gz
# ln -s /usr/local/src/apache-ant-1.9.6 /usr/local/ant
antへのパスも通しておく。
ANT_HOME=/usr/local/ant
PATH=$PATH:$ANT_HOME/bin

今回ccmakeで選んだオプションをキャプチャーしたので貼っておく。




ここからmakeしていく。
# make -j7
バリバリにwarningが出てるが、一旦、気にしない。気長に待つ。

エラーが出てこけた。

大域スコープ:
cc1plus: 警告: 認識できないコマンドラインオプション ‘-Wno-unnamed-type-template-args’ です
[ 47%] Linking CXX executable ../../bin/cpp-example-autofocus
../../lib/libopencv_world.so.3.0.0: `DefaultViewPort::staticMetaObject' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvWinProperties' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `CvWindow::staticMetaObject' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `CvTrackbar::staticMetaObject' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvPushButton' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for GuiReceiver' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvCheckBox' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvTrackbar' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for DefaultViewPort' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvWindow' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `CvButtonbar::staticMetaObject' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvRadioButton' に対する定義されていない参照です
../../lib/libopencv_world.so.3.0.0: `vtable for CvButtonbar' に対する定義されていない参照です
collect2: エラー: ld はステータス 1 で終了しました
samples/cpp/CMakeFiles/example_autofocus.dir/build.make:97: recipe for target 'bin/cpp-example-autofocus' failed
make[2]: *** [bin/cpp-example-autofocus] Error 1
CMakeFiles/Makefile2:3671: recipe for target 'samples/cpp/CMakeFiles/example_autofocus.dir/all' failed
make[1]: *** [samples/cpp/CMakeFiles/example_autofocus.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2

opencv_worldが悪さをしているみたいなので、一旦OFFにした。各種モジュールを1つのライブラリにするだけみたいなので、特に問題ないかなと。

あと、POLICYIDがどうのこうのと言われるので、CMakeList.txtに追記した。
if(POLICY CMP0045)
  cmake_policy(SET CMP0049 OLD)
endif()

if(POLICY CMP0059)
  cmake_policy(SET CMP0059 OLD)
endif()
再トライしたところ、うまくmake終了。make installもうまくいった。

ただ、ここまでだとsampleがインストールされないので、動作確認するまでにsampleもインストールしておく。
# cd /usr/local/src/opencv-3.0.0/build/samples
# make
この後、もうCMakeList.txtができるので、もう1度ccmake

# pwd
/usr/local/src/opencv-3.0.0/build/samples
# ccmake .
# make

これで/usr/local/src/opencv-3.0.0/samplesにサンプルがインストールされた。

実際に試してみる。

# /usr/local/src/opencv-3.0.0/samples/cpp/cpp-example-facedetect --cascade="/usr/local/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --scale=1.3 /usr/local/src/opencv-3.0.0/samples/data/lena.jpg 


出来た!!!
でもソースをコンパイルしたディレクトリ配下なので少し気持ち悪い。/usr/local/opencvの下にどうしたらインストールできるんやろう。

Fedora23にRPM Fusionリポジトリを追加する

このエントリーをはてなブックマークに追加

そういややってなかったので、Fedora23にRPM Fusionのリポジトリを追加しておく。

RPM Fusionは公式リポジトリに入っていないオープンソースのfreeとライセンス的にNGやソース非公開などのプロダクトが収録されたnonfreeの2つあるので両方いれておく。

ちなみにdnfのリポジトリ自体はまだ/etc/yum.repos.d/にある。

それっと追加。

# dnf install 'http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-23.noarch.rpm' 'http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-23.noarch.rpm'
メタデータの期限切れの確認は、0:24:26 前の Wed Nov 11 02:35:49 2015 に実施しました。
依存性が解決されました。
========================================================================================================================
 パッケージ                               アーキテクチャ        バージョン            リポジトリ                   容量
========================================================================================================================
インストール中:
 rpmfusion-free-release                   noarch                23-0.1                @commandline                 19 k
 rpmfusion-nonfree-release                noarch                23-0.1                @commandline                 19 k

トランザクションの要約
========================================================================================================================
インストール  2 Packages

合計容量: 39 k
インストール済み容量: 20 k
これでいいですか? [y/N]: y
パッケージをダウンロードしています:
トランザクションの確認を実行中...
トランザクションの確認に成功しました。
トランザクションのテストを実行中...
トランザクションのテストに成功しました。
トランザクションを実行中...
  インストール中  : rpmfusion-free-release-23-0.1.noarch                                                            1/2
  インストール中  : rpmfusion-nonfree-release-23-0.1.noarch                                                         2/2
警告: rpmfusion-nonfree-release-23-0.1.noarch: ヘッダー V4 RSA/SHA1 Signature、鍵 ID 5ca6c469: NOKEY
  検証中          : rpmfusion-nonfree-release-23-0.1.noarch                                                         1/2
  検証中          : rpmfusion-free-release-23-0.1.noarch                                                            2/2

インストール:
  rpmfusion-free-release.noarch 23-0.1                      rpmfusion-nonfree-release.noarch 23-0.1

完了しました!

無事終了。

2015年11月10日火曜日

特定サイトをクローリングする

このエントリーをはてなブックマークに追加
ある特定のドメインのサイトを一定階層までダウンロードしてみる。

/**
 * メイン処理
 */

// ライブラリ読み込み
var client = require('cheerio-httpcli');
var request = require('request');
var URL = require('url');
var fs = require('fs');
var path = require('path');

// 読み込み階層を今回は3までに指定
var LINK_LEVEL = 3;
// ダウンロード先
var TARGET_URL = "http://docs.opencv.org/3.0.0/";
var list = {};

// ダウンロード関数実行
downloadRec(TARGET_URL, 0);

/*
 * 関数定義
 */
function downloadRec(url, level){
 // 読み込み階層を超えてたら実行終了
 if( level >= LINK_LEVEL){
  return;
 }
 
 // listに追加されたurlがTRUE(ダウンロード済み)であれば抜ける
 if(list[url]){
  return;
 }
 
 list[url] = true;
 
 // 外部ドメインは無視する
 var us = TARGET_URL.split("/");
 us.pop();
 var base = us.join("/");
 if(url.indexOf(base) < 0){
  return;
 }
 
 client.fetch(url, {}, function(err, $, res){
  // エラーが返されたら終了
  if(err){
         console.log("Error", err);
         console.log("RESPONCE", res);
  }
  // aタグをすべてチェック
  $("a").each(function(idx){
   var href = $(this).attr("href");
   // リンク先がなければ終了
   if(!href){
    return;
   }
   
   // 相対パスを絶対パスへ変更
   href = URL.resolve(url, href);
   
   // アンカーリンクは無視
   href = href.replace(/\#.+$/, "");
   
   // リンク先のURLに対して再帰的に実行
   downloadRec(href, level + 1);
  });
  
  // URLの最後が’/’だけだったらindex.htmlを足す
  if(url.substr(url.length-1, 1) == "/"){
   url += "index.html";
  }
  
  // 3層までなのでURLを一旦’/’で分割し、最後から2つの要素を取り出し、再度’/’をつけてディレクトリパスにする。
  var savepath = url.split("/").slice(2).join("/");
  checkSaveDir(savepath);
  console.log(savepath);
  fs.writeFileSync(savepath, $.html());
  
 });
}

// 該当のディレクトリがあるかどうかチェック
function checkSaveDir(fname){
 var dir = path.dirname(fname);
 
 var dirlist = dir.split("/");
 var p = "";
 
 for(var i in dirlist){
  p += dirlist[i] + "/";
  if(!fs.existsSync(p)){
   fs.mkdirSync(p);
  }
 }
}
順調に行ってたら、このメッセージが出た。エラー処理を入れて確認してみる。
getall.js:37 $("a").each(function(idx){ ^ TypeError: $ is not a function     at Object.callback (/root/WebCrawler-NetAgent/ch02/getall.js:37:3)     at Object.module.exports.fail (/root/node_modules/cheerio-httpcli/lib/client.js:59:15)     at Object.<anonymous> (/root/node_modules/cheerio-httpcli/lib/client.js:191:21)     at Object.<anonymous> (/root/node_modules/cheerio-httpcli/lib/client.js:129:16)     at self.callback (/root/node_modules/cheerio-httpcli/node_modules/request/request.js:198:22)     at emitOne (events.js:77:13)     at Request.emit (events.js:169:7)     at null._onTimeout (/root/node_modules/cheerio-httpcli/node_modules/request/request.js:811:12)     at Timer.listOnTimeout (timers.js:92:15)
client.fetchの一番上にエラー処理を入れてみた。
:
:
 client.fetch(url, {}, function(err, $, res){
  if(err){
   console.log("Error", err);
   console.log("RESPONCE", res);
   return;
  }
  
  $("a").each(function(idx){
   var href = $(this).attr("href");
   if(!href){
    return;
   }
:
:
すると、約300ページほどタイムアウトで取得できていないことがわかった。ただURLを直接ブラウザで確認すると問題なさそうなので、なんでかなと思いつつ一旦スルー。ちなみにこんなエラー。
Error { [Error: ETIMEDOUT]   code: 'ETIMEDOUT',   connect: true,   url: 'http://docs.opencv.org/3.0.0/dd/de2/classcv_1_1AutoLock.html',   param: {} } RESPONCE undefined Error { [Error: ETIMEDOUT]   code: 'ETIMEDOUT',   connect: true,   url: 'http://docs.opencv.org/3.0.0/d7/d7b/classcv_1_1BackgroundSubtractorMOG2.html',   param: {} } RESPONCE undefined Error { [Error: ETIMEDOUT]   code: 'ETIMEDOUT',   connect: true,   url: 'http://docs.opencv.org/3.0.0/d0/d2e/classcv_1_1CommandLineParser.html',   param: {} }
こんなのが300個ほど。(正確には332個だった) 取得したのを確認してみるとこんな感じ。 あと404も1つあった。これは実際のサイトのURLをたどっても404だったのでプログラム的には問題なし。
Error { [Error: server status]   url: 'http://docs.opencv.org/3.0.0//3.0-last-rst',   param: {},   statusCode: 404 } RESPONCE IncomingMessage {   _readableState:    ReadableState {      objectMode: false,      highWaterMark: 16384,      buffer: [],      length: 0,      pipes: null,      pipesCount: 0,      flowing: true,      ended: true,      endEmitted: true,      reading: false,      sync: false,      needReadable: false,      emittedReadable: false,      readableListening: false,      defaultEncoding: 'utf8',      ranOut: false,      awaitDrain: 0,      readingMore: false,      decoder: null,      encoding: null,      resumeScheduled: false },   readable: false,   domain: null,   _events:    { end: [ [Function: responseOnEnd], [Function], [Function], [Function] ],      close: [ [Function], [Function] ],      data: [Function],      error: [Function] },   _eventsCount: 4,   _maxListeners: undefined,   socket:    Socket {      _connecting: false,      _hadError: false,      _handle: null,      _parent: null,      _host: 'docs.opencv.org',      _readableState:       ReadableState {         objectMode: false,         highWaterMark: 16384,         buffer: [],         length: 0,         pipes: null,         pipesCount: 0,         flowing: true,         ended: true,         endEmitted: true,         reading: false,         sync: false,         needReadable: false,         emittedReadable: false,         readableListening: false,         defaultEncoding: 'utf8',         ranOut: false,         awaitDrain: 0,         readingMore: false,         decoder: null,         encoding: null,         resumeScheduled: false },      readable: false,      domain: null,      _events:       { end: [Object],         finish: [Function: onSocketFinish],         _socketEnd: [Function: onSocketEnd],         free: [Function: onFree],         close: [Object],         agentRemove: [Function: onRemove],         drain: [Function: ondrain],         error: [Object],         data: [Function: socketOnData],         timeout: [Object] },      _eventsCount: 10,      _maxListeners: 0,      _writableState:       WritableState {         objectMode: false,         highWaterMark: 16384,         needDrain: false,         ending: true,         ended: true,         finished: true,         decodeStrings: false,         defaultEncoding: 'utf8',         length: 0,         writing: false,         corked: 0,         sync: false,         bufferProcessing: false,         onwrite: [Function],         writecb: null,         writelen: 0,         bufferedRequest: null,         lastBufferedRequest: null,         pendingcb: 0,         prefinished: true,         errorEmitted: false },      writable: false,      allowHalfOpen: false,      destroyed: true,      bytesRead: 383,      _bytesDispatched: 292,      _sockname: null,      _pendingData: null,      _pendingEncoding: '',      parser: null,      _httpMessage:       ClientRequest {         domain: null,         _events: [Object],         _eventsCount: 5,         _maxListeners: undefined,         output: [],         outputEncodings: [],         outputCallbacks: [],         outputSize: 0,         writable: true,         _last: true,         chunkedEncoding: false,         shouldKeepAlive: false,         useChunkedEncodingByDefault: false,         sendDate: false,         _removedHeader: {},         _contentLength: 0,         _hasBody: true,         _trailer: '',         finished: true,         _headerSent: true,         socket: [Circular],         connection: [Circular],         _header: 'GET /3.0.0//3.0-last-rst HTTP/1.1\r\nHost: docs.opencv.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36\r\nReferer: http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html\r\nAccept-Encoding: gzip, deflate\r\nConnection: close\r\n\r\n',         _headers: [Object],         _headerNames: [Object],         _onPendingData: null,         agent: [Object],         socketPath: undefined,         method: 'GET',         path: '/3.0.0//3.0-last-rst',         timeoutCb: [Function: emitTimeout],         parser: null,         res: [Circular] },      _idleTimeout: -1,      _idleNext: null,      _idlePrev: null,      _idleStart: 4136,      read: [Function],      _consuming: true,      write: [Function: writeAfterFIN] },   connection:    Socket {      _connecting: false,      _hadError: false,      _handle: null,      _parent: null,      _host: 'docs.opencv.org',      _readableState:       ReadableState {         objectMode: false,         highWaterMark: 16384,         buffer: [],         length: 0,         pipes: null,         pipesCount: 0,         flowing: true,         ended: true,         endEmitted: true,         reading: false,         sync: false,         needReadable: false,         emittedReadable: false,         readableListening: false,         defaultEncoding: 'utf8',         ranOut: false,         awaitDrain: 0,         readingMore: false,         decoder: null,         encoding: null,         resumeScheduled: false },      readable: false,      domain: null,      _events:       { end: [Object],         finish: [Function: onSocketFinish],         _socketEnd: [Function: onSocketEnd],         free: [Function: onFree],         close: [Object],         agentRemove: [Function: onRemove],         drain: [Function: ondrain],         error: [Object],         data: [Function: socketOnData],         timeout: [Object] },      _eventsCount: 10,      _maxListeners: 0,      _writableState:       WritableState {         objectMode: false,         highWaterMark: 16384,         needDrain: false,         ending: true,         ended: true,         finished: true,         decodeStrings: false,         defaultEncoding: 'utf8',         length: 0,         writing: false,         corked: 0,         sync: false,         bufferProcessing: false,         onwrite: [Function],         writecb: null,         writelen: 0,         bufferedRequest: null,         lastBufferedRequest: null,         pendingcb: 0,         prefinished: true,         errorEmitted: false },      writable: false,      allowHalfOpen: false,      destroyed: true,      bytesRead: 383,      _bytesDispatched: 292,      _sockname: null,      _pendingData: null,      _pendingEncoding: '',      parser: null,      _httpMessage:       ClientRequest {         domain: null,         _events: [Object],         _eventsCount: 5,         _maxListeners: undefined,         output: [],         outputEncodings: [],         outputCallbacks: [],         outputSize: 0,         writable: true,         _last: true,         chunkedEncoding: false,         shouldKeepAlive: false,         useChunkedEncodingByDefault: false,         sendDate: false,         _removedHeader: {},         _contentLength: 0,         _hasBody: true,         _trailer: '',         finished: true,         _headerSent: true,         socket: [Circular],         connection: [Circular],         _header: 'GET /3.0.0//3.0-last-rst HTTP/1.1\r\nHost: docs.opencv.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36\r\nReferer: http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html\r\nAccept-Encoding: gzip, deflate\r\nConnection: close\r\n\r\n',         _headers: [Object],         _headerNames: [Object],         _onPendingData: null,         agent: [Object],         socketPath: undefined,         method: 'GET',         path: '/3.0.0//3.0-last-rst',         timeoutCb: [Function: emitTimeout],         parser: null,         res: [Circular] },      _idleTimeout: -1,      _idleNext: null,      _idlePrev: null,      _idleStart: 4136,      read: [Function],      _consuming: true,      write: [Function: writeAfterFIN] },   httpVersionMajor: 1,   httpVersionMinor: 1,   httpVersion: '1.1',   complete: true,   headers:    { server: 'nginx',      date: 'Tue, 10 Nov 2015 09:58:11 GMT',      'content-type': 'text/html; charset=iso-8859-1',      vary: 'Accept-Encoding',      'content-encoding': 'gzip',      connection: 'close' },   rawHeaders:    [ 'Server',      'nginx',      'Date',      'Tue, 10 Nov 2015 09:58:11 GMT',      'Content-Type',      'text/html; charset=iso-8859-1',      'Vary',      'Accept-Encoding',      'Content-Encoding',      'gzip',      'Connection',      'close' ],   trailers: {},   rawTrailers: [],   upgrade: false,   url: '',   method: null,   statusCode: 404,   statusMessage: 'Not Found',   client:    Socket {      _connecting: false,      _hadError: false,      _handle: null,      _parent: null,      _host: 'docs.opencv.org',      _readableState:       ReadableState {         objectMode: false,         highWaterMark: 16384,         buffer: [],         length: 0,         pipes: null,         pipesCount: 0,         flowing: true,         ended: true,         endEmitted: true,         reading: false,         sync: false,         needReadable: false,         emittedReadable: false,         readableListening: false,         defaultEncoding: 'utf8',         ranOut: false,         awaitDrain: 0,         readingMore: false,         decoder: null,         encoding: null,         resumeScheduled: false },      readable: false,      domain: null,      _events:       { end: [Object],         finish: [Function: onSocketFinish],         _socketEnd: [Function: onSocketEnd],         free: [Function: onFree],         close: [Object],         agentRemove: [Function: onRemove],         drain: [Function: ondrain],         error: [Object],         data: [Function: socketOnData],         timeout: [Object] },      _eventsCount: 10,      _maxListeners: 0,      _writableState:       WritableState {         objectMode: false,         highWaterMark: 16384,         needDrain: false,         ending: true,         ended: true,         finished: true,         decodeStrings: false,         defaultEncoding: 'utf8',         length: 0,         writing: false,         corked: 0,         sync: false,         bufferProcessing: false,         onwrite: [Function],         writecb: null,         writelen: 0,         bufferedRequest: null,         lastBufferedRequest: null,         pendingcb: 0,         prefinished: true,         errorEmitted: false },      writable: false,      allowHalfOpen: false,      destroyed: true,      bytesRead: 383,      _bytesDispatched: 292,      _sockname: null,      _pendingData: null,      _pendingEncoding: '',      parser: null,      _httpMessage:       ClientRequest {         domain: null,         _events: [Object],         _eventsCount: 5,         _maxListeners: undefined,         output: [],         outputEncodings: [],         outputCallbacks: [],         outputSize: 0,         writable: true,         _last: true,         chunkedEncoding: false,         shouldKeepAlive: false,         useChunkedEncodingByDefault: false,         sendDate: false,         _removedHeader: {},         _contentLength: 0,         _hasBody: true,         _trailer: '',         finished: true,         _headerSent: true,         socket: [Circular],         connection: [Circular],         _header: 'GET /3.0.0//3.0-last-rst HTTP/1.1\r\nHost: docs.opencv.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36\r\nReferer: http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html\r\nAccept-Encoding: gzip, deflate\r\nConnection: close\r\n\r\n',         _headers: [Object],         _headerNames: [Object],         _onPendingData: null,         agent: [Object],         socketPath: undefined,         method: 'GET',         path: '/3.0.0//3.0-last-rst',         timeoutCb: [Function: emitTimeout],         parser: null,         res: [Circular] },      _idleTimeout: -1,      _idleNext: null,      _idlePrev: null,      _idleStart: 4136,      read: [Function],      _consuming: true,      write: [Function: writeAfterFIN] },   _consuming: true,   _dumped: false,   req:    ClientRequest {      domain: null,      _events:       { socket: [Object],         timeout: [Object],         response: [Function: bound ],         error: [Function: bound ],         drain: [Function] },      _eventsCount: 5,      _maxListeners: undefined,      output: [],      outputEncodings: [],      outputCallbacks: [],      outputSize: 0,      writable: true,      _last: true,      chunkedEncoding: false,      shouldKeepAlive: false,      useChunkedEncodingByDefault: false,      sendDate: false,      _removedHeader: {},      _contentLength: 0,      _hasBody: true,      _trailer: '',      finished: true,      _headerSent: true,      socket:       Socket {         _connecting: false,         _hadError: false,         _handle: null,         _parent: null,         _host: 'docs.opencv.org',         _readableState: [Object],         readable: false,         domain: null,         _events: [Object],         _eventsCount: 10,         _maxListeners: 0,         _writableState: [Object],         writable: false,         allowHalfOpen: false,         destroyed: true,         bytesRead: 383,         _bytesDispatched: 292,         _sockname: null,         _pendingData: null,         _pendingEncoding: '',         parser: null,         _httpMessage: [Circular],         _idleTimeout: -1,         _idleNext: null,         _idlePrev: null,         _idleStart: 4136,         read: [Function],         _consuming: true,         write: [Function: writeAfterFIN] },      connection:       Socket {         _connecting: false,         _hadError: false,         _handle: null,         _parent: null,         _host: 'docs.opencv.org',         _readableState: [Object],         readable: false,         domain: null,         _events: [Object],         _eventsCount: 10,         _maxListeners: 0,         _writableState: [Object],         writable: false,         allowHalfOpen: false,         destroyed: true,         bytesRead: 383,         _bytesDispatched: 292,         _sockname: null,         _pendingData: null,         _pendingEncoding: '',         parser: null,         _httpMessage: [Circular],         _idleTimeout: -1,         _idleNext: null,         _idlePrev: null,         _idleStart: 4136,         read: [Function],         _consuming: true,         write: [Function: writeAfterFIN] },      _header: 'GET /3.0.0//3.0-last-rst HTTP/1.1\r\nHost: docs.opencv.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36\r\nReferer: http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html\r\nAccept-Encoding: gzip, deflate\r\nConnection: close\r\n\r\n',      _headers:       { host: 'docs.opencv.org',         'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',         referer: 'http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html',         'accept-encoding': 'gzip, deflate' },      _headerNames:       { host: 'Host',         'user-agent': 'User-Agent',         referer: 'Referer',         'accept-encoding': 'Accept-Encoding' },      _onPendingData: null,      agent:       Agent {         domain: null,         _events: [Object],         _eventsCount: 1,         _maxListeners: undefined,         defaultPort: 80,         protocol: 'http:',         options: [Object],         requests: {},         sockets: [Object],         freeSockets: {},         keepAliveMsecs: 1000,         keepAlive: false,         maxSockets: Infinity,         maxFreeSockets: 256 },      socketPath: undefined,      method: 'GET',      path: '/3.0.0//3.0-last-rst',      timeoutCb: [Function: emitTimeout],      parser: null,      res: [Circular] },   request:    Request {      domain: null,      _events:       { error: [Function: bound ],         complete: [Function: bound ],         pipe: [Function],         end: [Object],         data: [Function] },      _eventsCount: 5,      _maxListeners: undefined,      callback: [Function],      followRedirect: true,      timeout: 30000,      headers:       { Host: 'docs.opencv.org',         'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',         Referer: 'http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html',         'Accept-Encoding': 'gzip, deflate' },      encoding: null,      method: 'GET',      uri:       Url {         protocol: 'http:',         slashes: true,         auth: null,         host: 'docs.opencv.org',         port: 80,         hostname: 'docs.opencv.org',         hash: null,         search: null,         query: null,         pathname: '/3.0.0//3.0-last-rst',         path: '/3.0.0//3.0-last-rst',         href: 'http://docs.opencv.org/3.0.0//3.0-last-rst' },      readable: true,      writable: true,      explicitMethod: true,      _qs:       Querystring {         request: [Circular],         lib: [Object],         useQuerystring: undefined,         parseOptions: {},         stringifyOptions: {} },      _auth:       Auth {         request: [Circular],         hasAuth: false,         sentAuth: false,         bearerToken: null,         user: null,         pass: null },      _oauth: OAuth { request: [Circular], params: null },      _multipart:       Multipart {         request: [Circular],         boundary: '03d2fef7-454d-4b17-85f7-74c8639b40e0',         chunked: false,         body: null },      _redirect:       Redirect {         request: [Circular],         followRedirect: true,         followRedirects: true,         followAllRedirects: false,         allowRedirect: [Function],         maxRedirects: 10,         redirects: [],         redirectsFollowed: 0,         removeRefererHeader: false },      _tunnel:       Tunnel {         request: [Circular],         proxyHeaderWhiteList: [Object],         proxyHeaderExclusiveList: [] },      setHeader: [Function],      hasHeader: [Function],      getHeader: [Function],      removeHeader: [Function],      localAddress: undefined,      pool: {},      dests: [],      __isRequestRequest: true,      _callback: [Function: bound ],      proxy: null,      tunnel: undefined,      setHost: false,      originalCookieHeader: undefined,      _jar: RequestJar { _jar: [Object] },      port: 80,      host: 'docs.opencv.org',      path: '/3.0.0//3.0-last-rst',      httpModule:       { IncomingMessage: [Object],         METHODS: [Object],         OutgoingMessage: [Object],         ServerResponse: [Object],         STATUS_CODES: [Object],         Agent: [Object],         globalAgent: [Object],         ClientRequest: [Object],         request: [Function],         get: [Function],         _connectionListener: [Function: connectionListener],         Server: [Object],         createServer: [Function],         Client: [Function: deprecated],         createClient: [Function: deprecated] },      agentClass: { [Function: Agent] super_: [Object], defaultMaxSockets: Infinity },      agent:       Agent {         domain: null,         _events: [Object],         _eventsCount: 1,         _maxListeners: undefined,         defaultPort: 80,         protocol: 'http:',         options: [Object],         requests: {},         sockets: [Object],         freeSockets: {},         keepAliveMsecs: 1000,         keepAlive: false,         maxSockets: Infinity,         maxFreeSockets: 256 },      _started: true,      href: 'http://docs.opencv.org/3.0.0//3.0-last-rst',      req:       ClientRequest {         domain: null,         _events: [Object],         _eventsCount: 5,         _maxListeners: undefined,         output: [],         outputEncodings: [],         outputCallbacks: [],         outputSize: 0,         writable: true,         _last: true,         chunkedEncoding: false,         shouldKeepAlive: false,         useChunkedEncodingByDefault: false,         sendDate: false,         _removedHeader: {},         _contentLength: 0,         _hasBody: true,         _trailer: '',         finished: true,         _headerSent: true,         socket: [Object],         connection: [Object],         _header: 'GET /3.0.0//3.0-last-rst HTTP/1.1\r\nHost: docs.opencv.org\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36\r\nReferer: http://docs.opencv.org/3.0.0/d9/df8/tutorial_root.html\r\nAccept-Encoding: gzip, deflate\r\nConnection: close\r\n\r\n',         _headers: [Object],         _headerNames: [Object],         _onPendingData: null,         agent: [Object],         socketPath: undefined,         method: 'GET',         path: '/3.0.0//3.0-last-rst',         timeoutCb: [Function: emitTimeout],         parser: null,         res: [Circular] },      timeoutTimer: null,      ntick: true,      response: [Circular],      originalHost: 'docs.opencv.org',      originalHostHeaderName: 'Host',      responseContent: [Circular],      _destdata: true,      _ended: true,      _callbackCalled: true },   toJSON: [Function: responseToJSON],   caseless:    Caseless {      dict:       { server: 'nginx',         date: 'Tue, 10 Nov 2015 09:58:11 GMT',         'content-type': 'text/html; charset=iso-8859-1',         vary: 'Accept-Encoding',         'content-encoding': 'gzip',         connection: 'close' } },   read: [Function],   body: <Buffer 1f 8b 08 00 00 00 00 00 00 03 4c 8e cd 0e 82 30 10 84 ef 3c c5 ca 1d 16 95 63 d3 83 fc 44 12 44 62 ea c1 23 a6 35 25 41 8a 6d d1 f8 f6 b6 70 f1 b4 99 ... >,   cookies: {}
今回はaタグのみで、imgタグやlinkタグ、scriptタグをたどっていないのでレイアウトは崩れて画像も表示できていなかった。
ちょっとタイムアウトが気持ち悪いけど、とりあえず再帰的に特定のドメイン以下のページを取得することはできた。
今日の作業

髪の毛切りに行ったりしてたら、今日はこれしかできなかった。。。