search
LoginSignup
86

More than 5 years have passed since last update.

posted at

PHPでスクレイピング【Goutte vs. Simple HTML DOM Parser】

PHPでスクレイピングをしようと思って検索すると、Simple HTML DOM Parserというライブラリと、Goutteというライブラリが紹介されてあるようです。

昔から存在してPHPスクレイピングの定番になっているのが、Simple HTML DOM Parserらしく、紹介記事も多い。

Goutteは、パフォーマンスが良いらしいが、比較すると記事が少ない。

そこで、本記事は、パフォーマンスバトルと実装方法についてまとめておきます。

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

1, Simple HTML DOM Parserのベンチマーク

1-1, 導入

Simple HTML DOM Parserの公式サイトにアクセスして、ダウンロードして、作業ディレクトリにsimple_html_dom.phpを配置する。

1-2, 実装

<?php
    require 'simple_html_dom.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_html('http://say-move.org/ranking.php');
        $rank = 0;
        foreach ($html->find('h3.ranking_ttl') as $element)
        {
            $titles[$rank] = $element->text();
            ++$rank;
        }

        // 解放する
        $html->clear();

        // 計測を終了する
        $totalOfTime += microtime(true) - $startTime;

        echo $totalOfTime . '<br/>';
    }

    print_r($titles);
    echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;

    unset($titles);
?>

find(‘h3.ranking_ttl’)でclass=”ranking_ttl”を取得している。

1-3, 計測結果

0.74032497406006
1.5220828056335
2.2691576480865
3.0349636077881
3.8007335662842
4.5622684955597
5.3352293968201
6.1218993663788
6.9005744457245
7.6647825241089
Array ( [0] => メカクシティアクターズ 第3話 「メカクシコード」・・略・・[29] => ダウンタウンDX 2014年5月1日放送分 )
平均実行時間: 0.76647825241089

2, Goutteのベンチマーク

2-1, 導入

GoutteのGitHubページから「You can also download the Goutte.phar file:」と書いてあるところから、goutte.pharをダウンロードして、作業ディレクトリに配置する。

2-2, 実装

<?php
    require 'goutte.phar';
    use Goutte\Client;

    header('Content-Type: text/html; charset=utf-8');

    $kNumberOfSamples = 10; // 何回サンプリングするか

    $titles = array(100);
    $totalOfTime = 0;
    for ($i = 0; $i < $kNumberOfSamples; ++$i)
    {
        // 計測を開始する
        $startTime = microtime(true);

        // ランキングにある全てのタイトルを取得する
        $client = new Client();
        $crawler = $client->request('GET', 'http://say-move.org/ranking.php');
        $rank = 0;
        $crawler->filter('h3.ranking_ttl')->each(function($element)
        {
            global $titles;
            global $rank;
            $titles[$rank] = $element->text();
            ++$rank;
        });

        // 解放する
        unset($client);
        unset($crawler);

        // 計測を終了する
        $totalOfTime += microtime(true) - $startTime;

        echo $totalOfTime . '<br/>';
    }

    print_r($titles);
    echo '<br/>平均実行時間: ' . $totalOfTime / $kNumberOfSamples;

    unset($titles);
?>

PHP初心者なので、ブロック内外でtitlesが二つ存在することになかなか気付きませんでした。

2-3, 計測結果

0.57542490959167
1.1356089115143
1.693286895752
2.2634289264679
2.8295919895172
3.4025230407715
3.9880549907684
4.5648419857025
5.1197459697723
5.6885468959808
Array ( [0] => メカクシティアクターズ 第3話 「メカクシコード」・・略・・[29] => ダウンタウンDX 2014年5月1日放送分 )
平均実行時間: 0.56885468959808

a. 結論

Goutteのほうが速いです!

メモリも計測したところ、Goutteのほうが少メモリです!
(ただしunsetでは少しメモりが漏れているようです。何か他の解放方法があるかもしれません)

「どっちがいい?」
私の結論はGoutteです。

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
What you can do with signing up
86