とほほのN88-BASIC日記 このページをアンテナに追加 RSSフィード

2013-11-08

CasperJS を Mac OS X にインストールする

CasperJS とは

CasperJS: CasperJS is a navigation scripting & testing utility for PhantomJS and SlimerJS written in Javascript

JavaScript で書けるスクレイピングとテストを便利にしてくれるツール。PhantomJS/SlimerJS を使っているので Mechanize とかと違い、JavaScript で表示制御しているようなページも扱える。

インストール

brew install casperjs

以上!というわけにはいかない。一緒にインストールされる Mac の PhantomJS のバイナリが腐っているので、このままでは UTF8 以外の日本語が文字化けしてしまって扱えない。PhantomJS をソースからリビルドする必要がある。

まずは phantomjs をアンインストール(しなくてもいいけど)。

brew uninstall phantomjs

phantomjs をリビルド

cd $HOME/local
git clone git://github.com/ariya/phantomjs.git
cd phantomjs
git checkout 1.9
./build.sh

最初に警告が出るとおり死ぬほど時間がかかるので昨日の公演をダウンロードして見ながら待つ。

終わったら phantomjs/bin にパスを通して動けば完了。

ln -s $HOME/local/bin/phantomjs $HOME/local/phantom/bin/phantomjs
casperjs

CasperJS で JQuery を使う

CasperJS は PhantomJS の機能を使って現在扱っているページに対して JS を差し込める。

var casper = require('casper').create({clientScripts: ['jquery-1.9.1.min.js']});

clientScripts にローカルの JQuery へのパスを指定する。phantom.incectJs() を使っているのでリモートのファイルは指定できない。

で、実際に使うには

var url ='http://www.akb48.co.jp/';
var casper = require('casper').create({clientScripts: ['jquery-1.9.1.min.js']});
casper.start(url, function() {
  this.echo($(title).text());
});
casper.run();

…では動かない。

ReferenceError: Can't find variable: $

とエラーが出る。evaluate() を使う必要がある。

var url ='http://www.akb48.co.jp/';
var casper = require('casper').create({clientScripts: ['jquery-1.9.1.min.js']});
casper.start(url, function() {
    var title = casper.evaluate(function(){
        return $('title');
    });
   this.echo(title.text());
});
casper.run();

…では動かない。

evaluate() は返り値に primitive object = JSON に変換可能なオブジェクトしか返せないので

var url ='http://www.akb48.co.jp/';
var casper = require('casper').create({clientScripts: ['jquery-1.9.1.min.js']});
casper.start(url, function() {
    var title = casper.evaluate(function(){
        return $('title').text();
    });
   this.echo(title);
});
casper.run();

とする必要がある。

これで

AKB48公式サイト

ちゃんと JQuery を使うことができる。

めんどい。非常にめんどい。

2011-11-28

UserAgent での iPhone / iPad / Android phone / Android Tablet の見分け方

if ($ua =~ /Android/) {
    if ($ua =~ /Mobile/) {
        $type = 'Android phone';
    } else {
        $type = 'Android tablet';
    }   
} elsif ($ua =~ /iPhone/) {
    $type = 'iPhone';
} elsif ($ua =~ /iPad/) {
    $type = 'iPad';
}

http://googlewebmastercentral-ja.blogspot.com/2011/05/android.html

2010-12-28

Kyoto Tycoon memcached plugin VS memcached のベンチを取ってみた

#!/usr/bin/env perl

use strict;
use warnings;

use Benchmark qw(:all);

use Cache::Memcached::Fast;

my $mf = Cache::Memcached::Fast->new( { servers => ['127.0.0.1:2010'] } );
my $mfm = Cache::Memcached::Fast->new( { servers => ['127.0.0.1:11211'] } );

my @keys = map { 'x' . rand } 0 .. 10000;
my $n = 100;

cmpthese(
    $n => +{
        'KT(memcached) set' => sub {
            $mf->set( $_ => rand ) for @keys;
        },  
        'Memcached (memcached) set' => sub {
            $mfm->set( $_ => rand ) for @keys;
        },  
    }   
);

cmpthese(
    $n => +{
        'KT(memcached) get' => sub {
            $mf->get($_) for @keys;
        },  
        'Memcached (memcached) get' => sub {
            $mfm->get($_) for @keys;
        },  
    }   
);
                            Rate     KT(memcached) set Memcached (memcached) set
KT(memcached) set         2.82/s                    --                      -15%
Memcached (memcached) set 3.34/s                   18%                        --
                            Rate     KT(memcached) get Memcached (memcached) get
KT(memcached) get         3.35/s                    --                      -12%
Memcached (memcached) get 3.79/s                   13%                        --

2010-12-22

KTのHTTPとMemcachedプロトコルのベンチを取ってみた

環境は以下の通り

  • mac mini 2.66GHz 4GB RAM
  • kyotocabinet 1.2.30
  • kyototycoon 0.9.18

KTをMemcachd pluginサポート起動

ktserver -plsv  /usr/local/lib/ktplugservmemc.dylib -plex 'port=2010'

ベンチを取ったコードはこんな感じ

とりあえずsetのベンチ

#!/usr/bin/env perl

use strict;
use warnings;

use Benchmark qw(:all);

use Cache::KyotoTycoon;
use Cache::Memcached::Fast;

my $kt = Cache::KyotoTycoon->new( host => '127.0.0.1', port => 1978 );
my $mf = Cache::Memcached::Fast->new( { servers => ['127.0.0.1:2010'] } );

my @keys = map { 'x' . rand } 0 .. 1000;
my $n = 10; 

cmpthese(
    $n => +{
        'Cache::Memcached::Fast' => sub {
            $mf->set( $_ => rand ) for @keys;
        },  
        'Cache::KyotoTycoon' => sub {
            $kt->set( $_ => rand ) for @keys;
        },  
    }   
);

結果

Cache::KyotoTycoon     5.52/s                     --                   -82%
Cache::Memcached::Fast 31.2/s                   466%                     --

HTTPオーバーヘッドが大きいので当たり前と言えば当たり前ですね。

getやバイナリプロトコルや他のストレージとの比較とかしてみたい。

2010-12-09

お手軽gitリモートリポジトリの作り方メモ

リモートリポジトリの作成

@example.com

cd ~
mkdir git
mkdir git/FooBar.git
cd git/FooBar.git
git --bare init --shared=true

ローカルリポジトリからpush

mkdir FooBar
cd FooBar
git init
touch README
git add README
git commit -a -m "initial import"
git remote add origin hidek@example.com:git/FooBar.git 
git push origin master

ローカルにclone

git clone hidek@example.com:git/FooBar.git

2010-10-17

Ubuntu 10.10 に XML::LibXMLをインストールする

一身上の都合でMacが使えなくなったのでUbuntuが入ったラップトップを引っ張り出してきたついでに、10.10をインストールして XML::LibXMLをインストールしようとしたらlibxml2が見つからないと怒られた。

hide@localhost:~$ perl Makefile.PL
enable native perl UTF8
running xml2-config...untested
Note: libxml2 2.7.7 was not tested with this XML::LibXML version.
looking for -lxml2... no
looking for -llibxml2... no
libxml2 not found
Try setting LIBS and INC values on the command line
Or get libxml2 from 
  http://xmlsoft.org/
If you install via RPMs, make sure you also install the -devel
RPMs, as this is where the headers (.h files) are.

Also, you may try to run perl Makefile.PL with the DEBUG=1 parameter
to see the exact reason why the detection of libxml2 installation
failed or why Makefile.PL was not able to compile a test program.

apt-get install libxml2-devしたけど見つからず。

http://www.simplicidade.org/notes/archives/2007/04/tip_xmllibxml_a.html

をみて

apt-get install zlib1g zlib1g-dev

したら通った。

2010-05-17

Jetty のベンチマークを取ってみた

- Linux version 2.6.18-164.el5xen

- Memory: 532480k

- http://localhost:8080/

Jetty 6

w/o keepalive

concurrency num [#/sec]
10 10000 1352.23
100 10000 3793.19
1000 10000 3836.32

w/ keepalive

concurrency num [#/sec]
10 10000 3351.16
100 10000 8065.65
1000 10000 6684.50

Jetty 7

w/o keepalive

concurrency num [#/sec]
10 10000 910.58
100 10000 2116.24
1000 10000 2488.36

w/ keepalive

concurrency num [#/sec]
10 10000 1333.15
100 10000 3350.84
1000 10000 4750.80

どっちとも負荷を与え続けると

2010-05-17 12:09:34.718:INFO::org.eclipse.jetty.io.nio.SelectorManager$SelectSet@3ff2947d JVM BUG(s) - injecting delay38 times

の警告を出したり

2010-05-17 11:31:19.828:WARN::EXCEPTION 
java.io.IOException: Too many open files
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:145)
        at org.eclipse.jetty.server.nio.SelectChannelConnector$1.acceptChannel(SelectChannelConnector.java:75)
        at org.eclipse.jetty.io.nio.SelectorManager$SelectSet.doSelect(SelectorManager.java:668)
        at org.eclipse.jetty.io.nio.SelectorManager.doSelect(SelectorManager.java:182)
        at org.eclipse.jetty.server.nio.SelectChannelConnector.accept(SelectChannelConnector.java:135)
        at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:852)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:437)
        at java.lang.Thread.run(Thread.java:619)

のExceptionをたまに吐くけど、よくわかんない。

--

追記:2010/05/17 19:40

http://b.hatena.ne.jp/kazuhooku/20100517#bookmark-21584084

id:kazuhooku「too many open files は ulimit -n == 1024 だからでは? 」

おっしゃるとおりです><

ファイルディスクリプタ増やしたら出なくなりました。

2010-02-28

QRコードを表示するapp.psgi

QRコードを表示するだけの簡単なお仕事を大量にさばきたいって言われたので書いてみた。

use Imager::QRCode;
use Plack::Request;

my $qrcode = Imager::QRCode->new(
    size          => 2,
    margin        => 2,
    version       => 1,
    level         => 'M',
    casesensitive => 1,
    lightcolor    => Imager::Color->new(255, 255, 255),
    darkcolor     => Imager::Color->new(0, 0, 0),
);

my $app = sub {
    my $req = Plack::Request->new(shift);

    my $url = $req->param('url')
        or
        return [400, ['Content-Type' => 'texxt/plain'], ['url is required']];

    my $img = $qrcode->plot($url);
    $img->write(data => \my $data, type => 'gif') or die $img->errstr;
    return [200, ['Content-Type' => 'image/gif'], [$data]];
};

これをStarmanで走らせて

starman -a app.psgi

ab -c 10 -n 100してみたら、うちのヘボサーバーでも247.78 [#/sec]くらいでた。

そういえば.cgiCGIスクリプトってよく言うけど.psgiPSGIスクリプトって呼べばいいのかな。PSGIアプリケーションでいいのか。

2010-02-22

cronologを32bit環境下で動かすときの注意

lighttpdを使ってるとログローテートにcronologをよく使うと風の噂でよく聞きます。

そんなcronologをそのまま32bit環境下で動かすとファイルサイズ2GBを超えて書き込めないですねーというありがたい説法をid:kazuhookuさんにしてもらいました。

要は32bitアプリケーションがopen(2)で2GBを超えるファイルにアクセスするためにはフラグとしてO_LARGEFILEを指定する必要があるのですが、2002-01-24で開発が止まっているcronologはその指定がないのでパッチを当ててやる必要があります。

--- src/cronolog.c.org  2010-02-23 00:49:18.000000000 +0900
+++ src/cronolog.c  2010-02-23 00:50:27.000000000 +0900
@@ -82,6 +82,8 @@
  * written to "file" (e.g. /dev/console) or to stderr if "file" is "-".
  */

+#define _GNU_SOURCE 1
+
 #include "cronoutils.h"
 #include "getopt.h"

@@ -394,13 +396,13 @@
       timestamp(*pnext_period), *pnext_period,
       *pnext_period - time_now));

-    log_fd = open(pfilename, O_WRONLY|O_CREAT|O_APPEND, FILE_MODE);
+    log_fd = open(pfilename, O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, FILE_MODE);

 #ifndef DONT_CREATE_SUBDIRS
     if ((log_fd < 0) && (errno == ENOENT))
     {
    create_subdirs(pfilename);
-   log_fd = open(pfilename, O_WRONLY|O_CREAT|O_APPEND, FILE_MODE);
+   log_fd = open(pfilename, O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, FILE_MODE);
     }
 #endif

rpmforgeのパッケージにもパッチはあたっていないのでついでにrpmforgeのSPECファイルを変更するとこんな感じ。

# $Id: cronolog.spec 5040 2007-01-02 20:35:37Z dag $
# Authority: dag

Summary: Log file rotator
Name: cronolog
Version: 1.6.2
Release: 1
License: GPL
Group: Applications/File
URL: http://cronolog.org/

Source: http://cronolog.org/download/cronolog-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Patch: cronolog-large-file.patch

%description
cronolog is a simple filter program that reads log file entries from
standard input and writes each entry to the output file specified by
a filename template and the current date and time. When the expanded
filename changes, the current file is closed and a new one opened.

cronolog is intended to be used in conjunction with a Web server,
such as Apache, to split the access log into daily or monthly logs.

%prep
%setup
%patch -p0

%build
%configure
%{__make} %{?_smp_mflags}

%install
%{__rm} -rf %{buildroot}
%{__make} install DESTDIR="%{buildroot}"

%clean
%{__rm} -rf %{buildroot}

%files
%defattr(-, root, root, 0755)
%doc AUTHORS ChangeLog COPYING NEWS README TODO
%doc %{_mandir}/man1/cronolog.1m*
%doc %{_mandir}/man1/cronosplit.1m*
%doc %{_infodir}/cronolog.info*
%{_sbindir}/cronolog
%{_sbindir}/cronosplit

%changelog
* Thu Dec 28 2006 Dag Wieers <dag@wieers.com> - 1.6.2-1
- Initial package. (Contributed by Christoper Maser)

とっとと64bitに移行しなさいという天の声が聞こえました。

2010-01-25

Macのデフォルトのファイルディクリプタ数は最大256

Mac

ab -c 1000 -n 10000 http://example.com

とかすると

socket: Too many open files (24)

とか怒られる。

CentOSとかなら大丈夫なのに。

おもむろに

ulimit -n

とかしてファイルディスクリプタの制限値を見ると、Mac

256

おふっ。

ちなみにCentOS 5.3だと1024

一時的に

ulimit -n 1024

で上げてやった。