ついでに絶対URLの取得ベンチマーク
スクレイピングにほとんど必須な作業に、相対パスからhttp://〜のURLを導きだす作業があるわけですが、Diggin_ScraperのデフォのアダプターにしているHTMLScraping classなんかは、正規表現+pearのNet/URLを組み合わせた関数(getAbsoluteUrl)が用意されてまして、それでももちろんOKというか、ピュアPHPなのでそれでいいじゃんていう訳ですが、pecl_httpを使うと正規表現やる必要がないんですよね。やったー。ほら、PHPって正規表現組み込みじゃないから使いにくいし〜。
前々から気になっていたので、ベンチマーク。ただし、私が作ったhttp_build_url仕様のやつは、全部のパターン網羅できてないかも。
絶対URLを取得する方法は、下記のコード以外に、Rinza_IEパッケージのものとか、あるわけですが今回は除外。
<?php require_once 'Benchmark/Iterate.php'; $bench = new Benchmark_Iterate(); error_reporting('E_FATAL');// E_STRICTでまくり class Url { /** * This is a part of HTMLScraping class * http://www.rcdtokyo.com/etc/htmlscraping/ */ public static function getAbsoluteUrlA($url, $base_url) { if (preg_match('/^[\w\+\-\.]+:/', $url) or false === $bases = @parse_url($base_url)) { return $url; } elseif (0 === strpos($url, '/')) { return "$bases[scheme]://$bases[host]".(isset($bases['port'])? ":$bases[port]": '').$url; } else { if (!isset($bases['path'])) { $bases['path'] = '/'; } require_once 'Net/URL.php'; return "$bases[scheme]://$bases[host]".(isset($bases['port'])? ":$bases[port]": ''). Net_URL::resolvePath(substr($bases['path'], 0, strrpos($bases['path'], '/') +1).$url); } } public static function getAbsoluteUrlB($url, $base_url) { $parse = parse_url($url); if (isset($parse["host"])) { $build = $url; } else { $uridir = pathinfo(parse_url($base_url, PHP_URL_PATH), PATHINFO_DIRNAME); $slash = strpos($uridir, '/'); if ($slash === false) { $build = http_build_url($base_url, array("path" => $url,), HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT); } else { $build = http_build_url($base_url, array("path" => $url,), HTTP_URL_JOIN_PATH | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT); } } return $build; } public static function getAbsoluteUrlB2($url, $base_url) { static $base_url; if(array_key_exists('host', parse_url($url))) { return $url; } else { if (strpos(pathinfo(parse_url($base_url, PHP_URL_PATH), PATHINFO_DIRNAME), '/') === false) { return http_build_url($base_url, array("path" => $url,), HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT); } else { return http_build_url($base_url, array("path" => $url,), HTTP_URL_JOIN_PATH | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT); } } } } $hrefs = array('/test.do?foo=bar', '../test.html', 'http://hoge.org/sample.php'); echo "--------getAbsoluteUrlA--------";echo PHP_EOL; foreach ($hrefs as $href) { // echo Url::getAbsoluteUrlA($href, 'http://hoge.org/foo/baa/here.do'); echo PHP_EOL; $bench->run(100, 'Url::getAbsoluteUrlA', $href, 'http://hoge.org/foo/baa/here.do'); $result = $bench->get(); var_dump($result['mean']); } echo "--------getAbsoluteUrlB--------";echo PHP_EOL; foreach ($hrefs as $href) { // echo Url::getAbsoluteUrlB($href, 'http://hoge.org/foo/baa/here.do');echo PHP_EOL; $bench->run(100, 'Url::getAbsoluteUrlB', $href, 'http://hoge.org/foo/baa/here.do'); $result = $bench->get(); var_dump($result['mean']); } echo "--------getAbsoluteUrlB2-------";echo PHP_EOL; foreach ($hrefs as $href) { // echo Url::getAbsoluteUrlB2($href, 'http://hoge.org/foo/baa/here.do');echo PHP_EOL; $bench->run(100, 'Url::getAbsoluteUrlB2', $href, 'http://hoge.org/foo/baa/here.do'); $result = $bench->get(); var_dump($result['mean']); }
結果
--------getAbsoluteUrlA-------- string(8) "0.000046" string(8) "0.001838" string(8) "0.000035" --------getAbsoluteUrlB-------- string(8) "0.000079" string(8) "0.000057" string(8) "0.000042" --------getAbsoluteUrlB2------- string(8) "0.000047" string(8) "0.000044" string(8) "0.000046"
PHP 5.2.4 (cli) (built: Aug 30 2007 07:06:31) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies with Zend Debugger v5.2.3, Copyright (c) 1999-2006, by Zend Technologies