目的
- Ubuntu Server 15.04でGoogleから検索結果を取得する
- 検索結果のキャプチャもとる
- ただしUbuntu Serverはインストール済みのものとする。
開発ツール一式他のInstall
$ sudo aptitude install build-essential freetype fontconfig python
build-essentialはこれがないと始まらない。freetypeとfontconfigは後々必要になる。
nodeのversion管理システムを入れる
nodeのversion管理にはnodebrewやらnvmやらnodeenvやらあるけど凄く入れやすいnodebrewにすることにした。
$ curl -L git.io/nodebrew | perl - setup
$ echo export PATH=$HOME/.nodebrew/current/bin:$PATH >> ~/.bashrc
$ source ~/.bashrc
$ nodebrew help
nodebrew 0.9.2
Usage:
nodebrew help Show this message
nodebrew install <version> Download and install a <version> (compile from source)
nodebrew install-binary <version> Download and install a <version> (binary file)
nodebrew uninstall <version> Uninstall a version
nodebrew use <version> Use <version>
nodebrew list List installed versions
nodebrew ls Alias for `list`
nodebrew ls-remote List remote versions
nodebrew ls-all List remote and installed versions
nodebrew alias <key> <version> Set alias to version
nodebrew unalias <key> Remove alias
nodebrew clean <version> | all Remove source file
nodebrew selfupdate Update nodebrew
nodebrew migrate-package <version> Install global NPM packages contained in <version> to current version
nodebrew exec <version> -- <command> Execute <command> specified <version>
Example:
# install from binary
nodebrew install-binary v0.10.22
# use a specific version number
nodebrew use v0.10.22
# io.js
nodebrew install-binary io@v1.0.0
nodebrew use io@v1.0.0
nodeを入れる
現在の安定版は公式サイトによるとv5.1.0らしい。とりあえず何も考えず入れてみよう、ライブラリとか動かなくてversion下げる事はあるかもしれない。
$ nodebrew install-binary v5.1.0
$ nodebrew use v5.1.0
$ node -v
v5.1.0
いつのversionからかはわからないがnodeを入れるとnpmも自動で入るのでガリガリ入れていく。その前に適当なワークディレクトリでも作ろう。
work directoryを作る
汚すかもしれないので移動
$ mkdir -p work/ScrapeSample && cd $_
npmを初期化する
ノードのバージョン管理するならモジュールもちゃんとバージョン管理しましょうね。ってことでinit
まぁモジュールはいれないけどね…。
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (ScrapeSample)
Sorry, name can no longer contain capital letters.
name: (ScrapeSample)
Sorry, name can no longer contain capital letters.
name: (ScrapeSample) scrape
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /home/molt/work/ScrapeSample/package.json:
{
"name": "scrape",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes)
Enterをぽんぽん押せばおk、と思ってたら名前長過ぎるから短くしろと怒られました。
2016/08/16追記
コメントにてご指摘。ありがてぇ
name: (ScrapeSample)
Sorry, name can no longer contain capital letters.
というエラーですが、「名前長過ぎるから短くしろと怒られました。」ということではなく、「もはや名前に大文字を含めることはできません。」というエラーと思われます。
どうみてもno longer
です。本当にありがとうございました。
「今時名前に大文字いれてるんじゃねーよ!」的なノリだろうか…。
スクレイピングのためのモジュールを入れる
nodejsでのスクレイピングはcheerio-httpcli
を使うのが鉄板。しかし動的なサイトも当然ある世の中はブラウザのオートメーションという切り口でスクレイピングをしていったほうが良いように思う。
スクショも撮りたいかもしれないし…。なのでphantomjs
をチョイスします。あとphantomjs
のラッパーであるcasperjs
も。
ココらへんもしかしたらProtractorのが良いのかもしれない。でもJavaはいれたくないんだ。他に何か良いライブラリあったら教えて下さい。casperjs
はコールバック地獄になるとかいうエントリもあるけど昔の話だよねぇ?
$ npm i -S -g phantomjs casperjs
ソースを書く
テストがてらキャプチャーを取得するコードを書く。CasperJsはCoffeeScriptをそのまま認識してくれるが今回はJavaScriptで書きます。
$ mkdir src
$ nano src/google.js
#!/usr/bin/env node
'use strict';
var target = 'http://google.co.jp';
var casper = require('casper').create();
casper.options.waitTimeout = 1000;
casper.start();
casper.viewport(1440,900);
casper.open(target);
casper.then(function(){
this.capture('cap.png');
});
casper.run();
$ casperjs src/google.js
でき…ん???
豆腐問題を解決する
参考:http://t-cyrill.hatenablog.jp/entry/2014/10/05/123803
日本語のフォントが入ってないので豆腐になりますよってことだ。
記事中ではversionの問題とあるけどUbuntuではversion変えてもだめだったので素直に日本語フォントを入れる。ちなみに別の記事では2.0.x系にあげれば解決するとか書いてあったんだが、公式サイトを見ながらBuildしようとしても失敗してしまったので1.9.8で進める…。
$ sudo aptitude install fonts-migmix
$ sudo nano /etc/fonts/local.conf
/etc/fonts/local.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="pattern">
<test qual="any" name="family">
<string>serif</string>
</test>
<edit name="family" mode="assign" binding="strong">
<string>MigMix 2P</string>
</edit>
</match>
</fontconfig>
あとはQuickStartを参考にリンクを取得する処理を書いていく。
#!/usr/bin/env node
'use strict';
function getLinks() {
var links = document.querySelectorAll('h3.r a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
var word = 'Qiita';
var target = 'http://google.co.jp';
var casper = require('casper').create();
var links = [];
casper.options.waitTimeout = 1000;
casper.start();
casper.viewport(1440,900);
casper.open(target);
casper.then(function(){
this.capture('google.png');
});
casper.then(function(){
links = this.evaluate(getLinks);
// 第一引数で対象のフォーム、第二引数でパラメータ、第三引数で入力後submitするか
this.fill('form[action="/search"]', { q: word }, true);
});
casper.then(function() {
this.capture('cap.png');
// aggregate results for the 'phantomjs' search
links = links.concat(this.evaluate(getLinks));
});
casper.run(function(){
this.echo(links.length + ' links found:');
this.echo(' - ' + links.join('\n - ')).exit();
});
結果
$ casperjs src/google.js
13 links found:
- /url?q=https://qiita.com/&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFggVMAA&usg=AFQjCNHu2rYnJu2kROQRZoO_pGa7aWxJhQ
- /url?q=http://qiita.com/tags&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIHDAB&usg=AFQjCNHAmSmV_E0SGT2hkBwq9CJmmBD3mg
- /url?q=https://teams.qiita.com/&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIHjAE&usg=AFQjCNEgQ_0ofyj5c1kqVRrGtim4qZezlQ
- /url?q=https://qiita.com/about&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIIDAC&usg=AFQjCNGlrUpC-22zqE4QsslqlROgRFVRqg
- /url?q=https://qiita.com/advent-calendar/2015&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIIjAF&usg=AFQjCNGfkNYqSumMEhIxzHagMgeAcCK0fQ
- /url?q=http://qiita.com/advent-calendar&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIJDAD&usg=AFQjCNGwyDgbWOn4b57KPhfVLNKG_77VaQ
- /url?q=http://kobito.qiita.com/&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QjBAIJjAG&usg=AFQjCNFN5t0GHo7wyt1UuUCGQcYFzcX99g
- /url?q=https://twitter.com/qiita&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFggoMAc&usg=AFQjCNGaTozeV5-fncLLq17MkKGvr37lDg
- /url?q=http://anond.hatelabo.jp/20150127003906&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFgguMAg&usg=AFQjCNHhQiAuVPxZVrBqIhbKHhpitpbM_g
- /search?q=Qiita&hl=ja&gbv=2&prmd=ivns&source=univ&tbm=nws&tbo=u&sa=X&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QqAIINQ
- /url?q=https://ferret-plus.com/1856&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFgg7MAs&usg=AFQjCNH0CxsyNTGFZWCd6hfdCcHDwsbcxQ
- /url?q=http://hrnabi.com/2015/03/11/6001/&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFghBMAw&usg=AFQjCNEO3eju-tqSvW2-ZP3FGBhba7Maww
- /url?q=http://qrank.wbsrv.net/&sa=U&ved=0ahUKEwil9a65g8XJAhUCGpQKHb5HCo8QFghHMA0&usg=AFQjCNFQ4Oy_40Cxx2Z1mkFdS-FUfhuG0A