2008/01/31


その1 3桁ごとに区切る - PleasureDelayerDiary はてなブックマーク数


Number.prototype.split3_1 = function() {
    var r = ""; 
    var s = this.toString().split("").reverse();
    for(var i = 0; i < s.length; i++) {
        if(i % 3 == 0 && i != 0 && s[i] != "-") {
            r = s[i] + "," + r
        } else {
            r = s[i] + r;
        }
    }  
    return r;
}

その2 iandeth. - javascriptで数値をカンマ区切り文字列に変換する関数メモ はてなブックマーク数


Number.prototype.split3_2 = function () {
    var to = String(this);
    var tmp = "";
    while (to != (tmp = to.replace(/^([+-]?\d+)(\d\d\d)/,"$1,$2"))){
        to = tmp;
    }
    return to;
}

その3 JavaScriptで数値を3桁ごとに区切る - 0x集積蔵 はてなブックマーク数


Number.prototype.split3_3 = function() {
    var m = (this &lt; 0) ? -1 : 1;
    var str = String(this*m).split('.');
    var arr = String(str[0]).split(''), len = Math.ceil(arr.length/3), res = [];
    for (var i =0;i&lt;len;++i) res.push(arr.splice(-3,3).join(''));
    return (m == -1 ? '-' : '') + res.reverse().join(',') + (str[1] ? '.' + str[1] : '');
};

その4 [JavaScript]数値を3桁ごとに区切る はてなブックマーク数


Number.prototype.split3_ore = function() {
  ('' + this).match(/(-?)([0-9]+)(\.[0-9]*)?/);
  var sp = [RegExp.$1, RegExp.$2, RegExp.$3];
  var x = Math.floor(sp[1].length / 3) * 3;
  var len = sp[1].length;
  return sp[0] + (sp[1].substr(0, len - x)) + (len - x == 0 ? '' : ',') +
         (sp[1].substr(len - x, x).match(/[0-9]{3}/g).join(',')) + sp[2];
}
私ならこう書く。
Number.prototype.split3 = function() {
  var r = "", s = this.toString().split("").reverse().join("").replace(/\d{3}/g,
    function(v){r+=v+',';return ''});
  return (r + s).split("").reverse().join("");
}
alert((1000000).split3()) // 1,000,000
文字列を逆にして、replaceに指定した関数で3桁毎にカンマを入れた結果と、空で置換したsubstituteの結果(あまった結果)を足す。その後文字列を逆にして戻す。
マイナスもたぶんOK。


追記1
しまった。チェック甘すぎ。
Number.prototype.split3 = function() {
  var r = "", s = this.toString().split("").reverse().join("").replace(/\d{3}/g,
    function(v){r+=v+',';return ''});
  if (!s.match(/\d/)) r = r.substr(0, r.length-1);
  return (r + s).split("").reverse().join("");
}
計測してみる!
mattnおそ!www
関数呼び出しコストか?
追記2
うむ。小数か...
Number.prototype.split3_mattn2 = function() {
  var r = '', s = this.toString();
  s.match(/(-?)([0-9]+)(\.[0-9]*)?/);
  var sp = [RegExp.$1, s = parseInt(RegExp.$2), RegExp.$3];
  while(s >= 1000) {
    r = ',' + (s%1000) + r;
    s = parseInt(s/1000);
  }
  return sp[0] + s + r + sp[2];
}
-12345678.2356を3桁ごとに区切るテスト

タイム測定



うむ。それでも遅い。
Posted at by




いぬビームさんが作ったはてなスターをプロフィールアイコンに変えるブックマークレットで遊んでたんですが、複数の日記を含んだページや、はてなブックマークに付けられた複数人への「はてなスター」ではいちいち数字をクリックして展開しなくてはなりません。
で...書いた。

久々javascript書いた。

今日も徹夜だ。

同情するなら☆おくれ。

ブックマークレット:はてなスターの数字を展開

ソースコードは↓
javascript:var d=document,e=d.createEvent('MouseEvents');if(typeof d.getElementsByClassName=='undefined')d.getElementsByClassName=function(c){var m=[];var n=d.body.getElementsByTagName('*');for(var i=0;i<n.length;i++)if(n[i].className == c)m.push(n[i]);return m;};void(0);d.getElementsByClassName('hatena-star-inner-count').forEach(function(i){e.initEvent('click', true, true);i.dispatchEvent(e)});void(0);
※たぶんfirefoxでしか動かない。
※ちなみに私のサイトでは数字が出るほど☆がないので、いぬビームさんとこでやるのがいいかと...
追記
修正しました。document.getElementsByClassNameがundefinedでした。
Posted at by




iTunesのライブラリ情報XMLファイルをアップロードする事で自分に合ったアーティスト情報を教えてくれるサービス、「veena!」の検索ボックスを使って、指定のアーティストに関連する
  • YouTube動画
  • Yahooオークション情報
をWeb::Scraperでスクレイピングしてみようと思います。
ソースはそれ程難しくもなく
#!/usr/bin/perl

use strict;
use warnings;

use URI;
use URI::Escape qw(uri_escape_utf8 uri_unescape);
use Web::Scraper;
use YAML::Syck;

my $artist = shift || 'Ozzy Ozbourne';
my $uri = URI->new('http://www.veena.jp/srch_artist.php?artist_name='
    . uri_escape_utf8($artist));

my $youtube_list = scraper {
    process '//table[@class="info_tbl"]/tr/td',
        'video[]' => scraper {
            process '//a[1]', url => sub {
                my $url = shift->attr('href');
                $url =~ s/^.*\?url=(.*)$/$1/;
                uri_unescape($url);
            };
            process '//a[2]', title => 'TEXT';
            process '//img', image => '@src';
        };
    result 'video';
};

my $auction_list = scraper {
    process '//table[@class="info_tbl"]/tr/td',
        'auction[]' => scraper {
            process '//a[1]', url => '@href';
            process '//a[2]', title => 'TEXT';
            process '//img', image => '@src';
        };
    result 'auction';
};

my $artist_list = scraper {
    process '//a[contains(@href, "artist.php")]',
        'artists[]' => scraper {
            process 'a', id => sub {
                my $url = shift->attr('href');
                $url =~ s/^.*id=(.*)$/$1/;
                $url;
            };
            process 'a', 'youtube' => sub {
                my $url = shift->attr('href');
                $url =~ s/artist\.php/http:\/\/veena.jp\/list_youtube\.php/;
                my $list = $youtube_list->scrape(URI->new($url));
                \@$list;
            };
            process 'a', 'auction' => sub {
                my $url = shift->attr('href');
                $url =~ s/artist\.php/list_auction\.php/;
                my $list = $auction_list->scrape(URI->new_abs($url, $uri));
                \@$list;
            };
            process 'a', name => 'TEXT';
        }
};
my $result = $artist_list->scrape($uri);
warn Dump $result;
って感じ。YouTube動画情報一覧とYahooオークション情報はアーティスト情報にぶら下がる形で出力したかったので検索結果一覧用のscraperとその結果を取得するscraperを親子関係にしてあります。
結構一覧としてはキレイに出力されているかと思います。
---
artists: 
  - 
    auction: 
      - 
        image: !!perl/scalar:URI::http http://ac.c.yimg.jp/7/1026/1783/000/img305.auctions.yahoo.co.jp/users/6/4/6/7/rosiertrueblue-thumb-119657918759294.jpg
        title: Ozzy Osbourne
        url: !!perl/scalar:URI::http http://page.auctions.yahoo.co.jp/jp/auction/108393777
      - 
        image: !!perl/scalar:URI::http http://ac.c.yimg.jp/7/1022/1783/000/img245.auctions.yahoo.co.jp/users/6/4/6/7/rosiertrueblue-thumb-119657997018368.jpg
        title: Ozzy Osbourne
        url: !!perl/scalar:URI::http http://page11.auctions.yahoo.co.jp/jp/auction/n61267094
      - 
        image: !!perl/scalar:URI::http http://a1017.lm.a.yimg.com/7/1017/1783/000/img257.auctions.yahoo.co.jp/users/8/2/8/3/kokita74-thumb-119486785113507.jpg
        title: Ozzy Osbourne
        url: !!perl/scalar:URI::http http://page8.auctions.yahoo.co.jp/jp/auction/h52088580
   ...
    id: 216546
    name: Randy Rhoads (Ozzy Ozbourne)
    youtube:
      -
        image: !!perl/scalar:URI::http http://img.youtube.com/vi/MEUbYkLe_wo/default.jpg
        title: Ozzy Ozbourne's top 10 songs
        url: http://www.youtube.com/watch?v=MEUbYkLe_wo
      - 
        image: !!perl/scalar:URI::http http://img.youtube.com/vi/GLtjWi4qkIY/default.jpg
        title: Goodbye to Romance - Ozzy/Randy Rhoads (solo)
        url: http://www.youtube.com/watch?v=GLtjWi4qkIY
      - 
        image: !!perl/scalar:URI::http http://img.youtube.com/vi/AQqbNHhBWcI/default.jpg
        title: iron man
        url: http://www.youtube.com/watch?v=AQqbNHhBWcI
   ...
Ozzy OzbourneのキーワードでRandy Rhoadsも引っかかってウハウハです。
で、このYAMLをどうするか...
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->agent('Mozilla');
for my $artist (@{$result->{artists}}) {
  for my $video (@{$artist->{youtube}}) {
    my $url = $video->{url};
    my $req = HTTP::Request->new(GET => $url);
    $req->header('Accept-Encoding', 'identity');
    my $res = $ua->request($req);
    if ($res->is_error) {
      if ((my $verify_url = $res->request->uri) =~ /\/verify_age\?/) {
        my $verify_req = HTTP::Request->new(POST => $verify_url, {action_confirm => 'Confirm'});
        $res = $ua->request($verify_req);
        $res = $ua->request($req) if $res->is_success;
      }
    }
    if ($res->content =~ /video_id=([^&]+)&l=\d+&t=([^&]+)/gms) {
      my $flv = "http://youtube.com/get_video?video_id=$1&t=$2";
      print "Downloading $flv\n";
      my $download_req = HTTP::Request->new(GET => $flv);
      $download_req->referer($url);
      my $res = $ua->request($download_req);
      if ($res->is_success) {
        open FH, ">$2.flv";
        binmode FH;
        print FH $res->content;
        close FH;
        print "Downloaded $2.flv\n";
      } else {
        print "Failed to download $2.flv\n";
      }
    } else {
      print "Not found flv file\n";
    }
  }
}
やっぱこうなりますわね...

mattn the crazy train scraper!
Posted at by