27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

~2回戦~ PHPでスクレイピング【Goutte vs. PHP Standard APIs】

Last updated at Posted at 2014-05-04

1回戦、 Goutte は Simple HTML DOM Parser 相手に、平均0.2s程度の差をつけて、勝利しました。(参考:PHPでスクレイピング【Goutte vs. Simple HTML DOM Parser】

勝利を称える声の中、ある強者の噂を私は耳にしました。

[引用]機能性ではちょっと劣りますが、パフォーマンス最優先ならpreg_match 関数PHPネイティブの DOMこういった選択肢もアリでしょうね。

たしかに。パフォーマンスを比べるならば、間違いなくオリジナルの関数の速度に勝つ事はないでしょう。
ですが、私のような初心者が組んだ一例として、Goutteの速度を上回ることが難しい例を紹介します。

そこで、2回戦として、 Goutte vs. preg_match vs. DOM でパフォーマンスバトルを行います。

1回戦と同じく、「SayMove!のランキングページから、動画のタイトルを取得する」でベンチマーク対決していただきます。

0, Goutteのベンチコート

時間帯によって差が生まれるので、今回も計測しなおします。
ソースコードはこの前と同じソースコードを使用します。
(参考: gist.github.com/soarcreator/11494901#file-file1-php)

平均実行時間: 0.57205934524536 でした。

1, preg_matchのベンチコート

1-1, 実装

<?php
    header('Content-Type: text/html; charset=utf-8');
     
    $kNumberOfSamples = 10; // 何回サンプリングするか
     
    $titles = array();
    $totalOfTime = 0;
    for ($i = 0; $i < $kNumberOfSamples; ++$i)
    {
        // 計測を開始する
        $startTime = microtime(true);
         
        // ランキングにある全てのタイトルを取得する
        $html = file_get_contents('http://say-move.org/ranking.php');
        if (preg_match_all('/<h3[\s]class="ranking_ttl"><[^>]*>(.*?)<[^>]*><\/h3>/s', $html, $elements))
        {
            $rank = 0;
            foreach ($elements[1] as $title)
            {
                $titles[$rank++] = $title;
            }
             
            // 解放する
            unset($elements);
            unset($title);
        }
        else
        {
            echo 'Not Found';
        }
         
        // 計測を終了する
        $totalOfTime += microtime(true) - $startTime;
         
        echo $totalOfTime . '<br/>';
    }
     
    print_r($titles);
    echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;
     
    unset($titles);
?>

正規表現わからないなりに頑張りましたが、効率が悪かったら、すいません。

1-2, 計測結果

0.69346404075623
1.3898799419403
2.0906138420105
2.7815208435059
3.479859828949
4.1586039066315
4.8545868396759
5.5568058490753
6.2275168895721
6.9227838516235
Array ( [0] => 【映画】THE GREY 凍える太陽 (吹替え)・・略・・[29] => ブラマヨとゆかいな仲間たち アツアツっ )
平均実行時間: 0.69227838516235

なななんと!
PHPのスタンダード正規表現APIが、Goutteより遅いことがわかりました!

2, DOMのベンチマーク

2-1, 実装

とりあえず、途中まで実装しましたが、

<?php
    header('Content-Type: text/html; charset=utf-8');
    
    $kNumberOfSamples = 10; // 何回サンプリングするか
    
    $titles = array();
    $totalOfTime = 0;
    for ($i = 0; $i < $kNumberOfSamples; ++$i)
    {
        // 計測を開始する
        $startTime = microtime(true);
         
        // ランキングにある全てのタイトルを取得する
        $html = new DOMDocument();
        $html->loadHTMLFile('http://say-move.org/ranking.php');
         
        // 計測を終了する
        $totalOfTime += microtime(true) - $startTime;
         
        echo $totalOfTime . '<br/>';
    }
     
    print_r($titles);
    echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;
     
    unset($titles);
?>

2-2, 計測結果

この時点で、

0.69660210609436
1.3984050750732
2.1059851646423
2.8011412620544
3.4911031723022
4.1912860870361
4.9223821163177
5.6201391220093
6.3140251636505
7.0278391838074
Array ( )
平均実行時間: 0.70278391838074

と遅いので、以降実装をするのをやめました。

a. 結論

私の書いたコードではGoutteがとりあえず速かったのですが、当然GoutteはStandard APIで実装されていますから、もっと頑張れば必ずStandard APIが勝利するでしょう。

Goutteが内部で何をしているかは、本記事では、明らかにしませんが、オープンソースなので、ダウンロードすれば読むことができます。

Goutteのダウンロード&導入方法などは一つ前の記事に書いてあります。よろしければお読み下さい。

27
28
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?