プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP、GoogleのCustom Search APIを使ってみる(5):検索結果を100件取得する
GoogleのCustom Search APIを使ってみる(4):エラー処理を追加してみる」の続きです。

今回は検索結果を100件取得してみます。

Custom Search APIから取得できる検索結果は1回の実行につき最大10件です。
11件以上取得しようとすると、エラーになります。
※ちなみに、取得件数を10件未満にしたい場合は、パラメータに「num」を指定します。

ですから、取得開始位置を変えて、ぐ~るぐ~ると処理を繰り返す形で100件取得します。

1回目:1位から10位までを取得
2回目:11位から20位までを取得
3回目:21位から30位までを取得
   ・
   ・
   ・
10回目:91位から100位までを取得

の流れです。

なお、2016年6月現在のCustom Search APIの仕様では、
取得できる件数は100件(100位まで)です。
101位以降を取得する条件指定でAPIを実行すると

HTTP/1.0 400 Bad Request

と怒られます。

それでは、見ていきましょう。

いきなりですが、サンプルですφ(--)

<?php

//------------------------------------
// 定数設定
//------------------------------------
//APIキー
$apiKey = "【取得したAPIキー】";

//検索エンジンID
$searchEngineId = "【取得した検索エンジンID】";

//検索用URL
$baseUrl = "https://www.googleapis.com/customsearch/v1?";

//取得開始位置
$startNum = 1;

//取得回数(APIを最大何回呼び出すか)
define("PAGE_GET_CNT", 10);


try {
    //--------------------------
    // 検索キーワード取得
    //--------------------------
    //$query = $_POST['q'];
    //$query = $_GET['q'];
    $query = "PHP site:piyopiyocs.blog115.fc2.com";

    for($i = 1; $i <= PAGE_GET_CNT; $i++){

        //------------------------------------
        // リクエストパラメータ生成
        //------------------------------------
        $paramAry = array(
                        'q' => $query,
                        'key' => $apiKey,
                        'cx' => $searchEngineId,
                        'alt' => 'json',
                        'start' => $startNum
                );
        $param = http_build_query($paramAry);

        //------------------------------------
        // 実行&結果取得
        //------------------------------------
        $reqUrl = $baseUrl . $param;
        $retJson = @file_get_contents($reqUrl, true);
        if($retJson === false){
            throw new Exception("取得失敗!:" . $http_response_header[0]);
        }

        $ret = json_decode($retJson, true);

        //------------------------------------
        // 結果表示
        //------------------------------------

        //画面表示
        //var_dump($ret);

        //JSON形式でファイル出力
        file_put_contents(dirname(__FILE__) . "/data/ret_" . $startNum . "_" . date('Ymd_His') . ".txt", $retJson);

        //項目を画面表示
        $num = $startNum;
        foreach($ret['items'] as $value){
            echo "順位:" . $num . "<br>\n";
            echo "タイトル:" . $value['title'] . "<br>\n";
            echo "URL:" . $value['link'] . "<br>\n";
            echo "-------------------------------------------------------------------------<br>\n";

            $num++;
        }

        //------------------------------------
        // 次ページの取得条件を設定
        //------------------------------------
        if(isset($ret['queries']['nextPage'][0]['startIndex'])){
            //次ページがあれば、取得開始位置を設定
            $startNum = $ret['queries']['nextPage'][0]['startIndex'];
        }else{
            //次ページがなければ、ループを抜ける
            break;
        }
    }

} catch (Exception $e) {
    print "エラー:" . $e->getMessage();
}

実行結果ですφ(--)

順位:1
タイトル:PHP・PDO、SQL実行時のエラーをExceptionで捕捉する|マコトの ...
URL:http://piyopiyocs.blog115.fc2.com/blog-entry-657.html
-------------------------------------------------------------------------
順位:2
タイトル:PHP、連想配列の並び順序あれこれ|マコトのおもちゃ箱 ~ぼへぼへ自 ...
URL:http://piyopiyocs.blog115.fc2.com/blog-entry-252.html
-------------------------------------------------------------------------

(中略)

-------------------------------------------------------------------------
順位:99
タイトル:MySQL、ランダムで取得したレコードに対してページング処理を行う ...
URL:http://piyopiyocs.blog115.fc2.com/blog-entry-1058.html
-------------------------------------------------------------------------
順位:100
タイトル:Windows7環境のIISを削除する|マコトのおもちゃ箱 ~ぼへぼへ自営業 ...
URL:http://piyopiyocs.blog115.fc2.com/blog-entry-509.html
-------------------------------------------------------------------------

今回追加した処理のポイントは

1.APIの呼び出し処理を最大10回繰り返す
2.APIの戻りから次の10件の取得開始位置を取り出す
3.「2.」の結果を取得開始位置に設定してAPIを再呼び出し

です。

for($i = 1; $i <= PAGE_GET_CNT; $i++){

//あれやこれやの処理

}

の記述が1に相当する処理です。

//------------------------------------
// 次ページの取得条件を設定
//------------------------------------
if(isset($ret['queries']['nextPage'][0]['startIndex'])){
    //次ページがあれば、取得開始位置を設定
    $startNum = $ret['queries']['nextPage'][0]['startIndex'];
}else{
    //次ページがなければ、ループを抜ける
    break;
}

の記述が2と3に相当する処理です。

APIからの戻りをprint_r()関数で表示すると、以下のような内容が表示されます。

Array
(
    [kind] => customsearch#search
    [url] => Array
        (
            [type] => application/json
            [template] => https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&cref={cref?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json
        )

    [queries] => Array
        (
            [request] => Array
                (
                    [0] => Array
                        (
                            [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
                            [totalResults] => 308
                            [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
                            [count] => 10
                            [startIndex] => 1
                            [inputEncoding] => utf8
                            [outputEncoding] => utf8
                            [safe] => off
                            [cx] => 【取得した検索エンジンID】
                        )

                )

            [nextPage] => Array
                (
                    [0] => Array
                        (
                            [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
                            [totalResults] => 308
                            [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
                            [count] => 10
                            [startIndex] => 11
                            [inputEncoding] => utf8
                            [outputEncoding] => utf8
                            [safe] => off
                            [cx] => 【取得した検索エンジンID】
                        )

                )

        )

    [context] => Array
        (
            [title] => test01
        )

    [searchInformation] => Array
        (
            [searchTime] => 0.330428
            [formattedSearchTime] => 0.33
            [totalResults] => 308
            [formattedTotalResults] => 308
        )

    [items] => Array
        (
            [0] => Array
                (
                    [kind] => customsearch#result
                    [title] => PHP・PDO、SQL実行時のエラーをExceptionで捕捉する|マコトの ...
                    [htmlTitle] => <b>PHP</b>・PDO、SQL実行時のエラーをExceptionで捕捉する|マコトの ...
                    [link] => http://piyopiyocs.blog115.fc2.com/blog-entry-657.html
                    [displayLink] => piyopiyocs.blog115.fc2.com
                    [snippet] => PHP・PDO、SQL実行時のエラーをExceptionで捕捉する」についてです。主にシステム
開発中に調べたことをメモしています。
                    [htmlSnippet] => <b>PHP</b>・PDO、SQL実行時のエラーをExceptionで捕捉する」についてです。主にシステム<br>
開発中に調べたことをメモしています。
                    [cacheId] => q-2uHo1pK44J
                    [formattedUrl] => piyopiyocs.blog115.fc2.com/blog-entry-657.html
                    [htmlFormattedUrl] => piyopiyocs.blog115.fc2.com/blog-entry-657.html
                    [pagemap] => Array
                        (
                            [metatags] => Array
                                (
                                    [0] => Array
                                        (
                                            [author] => ササキマコト
                                        )

                                )

                        )

                )

            [1] => Array
                (
                    [kind] => customsearch#result
                    [title] => PHP、連想配列の並び順序あれこれ|マコトのおもちゃ箱 ~ぼへぼへ自 ...
                    [htmlTitle] => <b>PHP</b>、連想配列の並び順序あれこれ|マコトのおもちゃ箱 ~ぼへぼへ自 ...
                    [link] => http://piyopiyocs.blog115.fc2.com/blog-entry-252.html
                    [displayLink] => piyopiyocs.blog115.fc2.com
                    [snippet] => 私も何となくそう思っていたのですが、 よく考えたらPHPの連想配列は並び順保持され
るよね(--? そもそもPHPでは配列と連想配列ってぶっちゃけ同じだし連想配列(
配列)をソートする関数があるってことは連想配列にも並び順の概念があるんじゃね(-
-?
                    [htmlSnippet] => 私も何となくそう思っていたのですが、 よく考えたら<b>PHP</b>の連想配列は並び順保持され<br>
るよね(--? そもそも<b>PHP</b>では配列と連想配列ってぶっちゃけ同じだし連想配列(<br>
配列)をソートする関数があるってことは連想配列にも並び順の概念があるんじゃね(-<br>
-?
                    [cacheId] => s1Z57hgL2K4J
                    [formattedUrl] => piyopiyocs.blog115.fc2.com/blog-entry-252.html
                    [htmlFormattedUrl] => piyopiyocs.blog115.fc2.com/blog-entry-252.html
                    [pagemap] => Array
                        (
                            [metatags] => Array
                                (
                                    [0] => Array
                                        (
                                            [author] => ササキマコト
                                        )

                                )

                        )

                )

(以下略)

)

見にくいので、必要なところだけバラしてみましょう。
戻り値の配列には「queries」をキーに持つ要素があります。
$ret['queries']でアクセスできる要素です。

[queries] => Array
    (
        [request] => Array
            (
                [0] => Array
                    (
                        [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
                        [totalResults] => 308
                        [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
                        [count] => 10
                        [startIndex] => 1
                        [inputEncoding] => utf8
                        [outputEncoding] => utf8
                        [safe] => off
                        [cx] => 【取得した検索エンジンID】
                    )

            )

        [nextPage] => Array
                (
                    [0] => Array
                    (
                        [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
                        [totalResults] => 308
                        [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
                        [count] => 10
                        [startIndex] => 11
                        [inputEncoding] => utf8
                        [outputEncoding] => utf8
                        [safe] => off
                        [cx] => 【取得した検索エンジンID】
                    )

            )

    )

$ret['queries']には「nextPage」をキーに持つ要素があります。
$ret['queries']['nextPage']でアクセスできる要素です。
これが、次の10件に関する情報が入っている要素です。

[nextPage] => Array
        (
            [0] => Array
            (
                [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
                [totalResults] => 308
                [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
                [count] => 10
                [startIndex] => 11
                [inputEncoding] => utf8
                [outputEncoding] => utf8
                [safe] => off
                [cx] => 【取得した検索エンジンID】
            )

    )

$ret['queries']['nextPage']でアクセスできる要素は要素数が1の配列です。
実際には$ret['queries']['nextPage'][0]でアクセスすることになります。

[0] => Array
(
    [title] => Google Custom Search - PHP site:piyopiyocs.blog115.fc2.com
    [totalResults] => 308
    [searchTerms] => PHP site:piyopiyocs.blog115.fc2.com
    [count] => 10
    [startIndex] => 11
    [inputEncoding] => utf8
    [outputEncoding] => utf8
    [safe] => off
    [cx] => 【取得した検索エンジンID】
)

$ret['queries']['nextPage'][0]には「startIndex」をキーに持つ要素があります。
$ret['queries']['nextPage'][0]['startIndex']でアクセスできる要素です。

[startIndex] => 11

お待たせしました。
$ret['queries']['nextPage'][0]['startIndex']に次の10件の取得開始位置が入っています。

ということで

//------------------------------------
// 次ページの取得条件を設定
//------------------------------------
if(isset($ret['queries']['nextPage'][0]['startIndex'])){
    //次ページがあれば、取得開始位置を設定
    $startNum = $ret['queries']['nextPage'][0]['startIndex'];
}else{
    //次ページがなければ、ループを抜ける
    break;
}

の処理では、$ret['queries']['nextPage'][0]['startIndex']の値を
次の10件の取得開始位置として$startNumに設定しています。

あとは次のループで、取得開始位置が新しい状態でAPIが呼ばれます。

なお、次の10件が無い場合は、$ret['queries']['nextPage']自体がありません。
検索結果をすべて取得した場合は、elseのbreakするルートに入ります。

また、検索結果が100件を超える場合には、
100位まで取得しても$ret['queries']['nextPage']があります。
startIndexが「101」の$ret['queries']['nextPage']が登場するのです。

そのため、$ret['queries']['nextPage'][0]['startIndex']の有無のみを条件にしてループを回すと
startIndexに「101」を設定してAPIを呼び出すことになるので、APIの戻りがエラーになります。

ループをwhileではなくfor文にして

for($i = 1; $i <= PAGE_GET_CNT; $i++){

//あれやこれやの処理

}

としているのは、それが理由です。
次の10件の有無によらず、10回(100件まで)取得したら処理を抜けるための措置です。

ふぃ~、長々と書きましたが、そんなところでしょうか。

あっ、そうそう。
Custom Search APIを無料で使う場合、1日最大100リクエストまでです。
つまり、本ページ記載のサンプルプログラムを10回実行したら無料分が終わります。

それを避けるためにも、PAGE_GET_CNTの値は3くらいにしてから動かした方が良いと思います。
取得件数が100件ではなく30件になりますけどね。
3でも10でも処理の流れは同じです。

何だかんだで長くなっちゃいましたね。
読むのも疲れたことでしょう。

お疲れ様でした\(--)/

■目次
GoogleのCustom Search APIを使ってみる(1):事前準備1、APIキーを取得する
GoogleのCustom Search APIを使ってみる(2):事前準備2、検索エンジンの設定をする
GoogleのCustom Search APIを使ってみる(3):最低限の動作を確認できるPHPのサンプルプログラム
GoogleのCustom Search APIを使ってみる(4):エラー処理を追加してみる
・GoogleのCustom Search APIを使ってみる(5):検索結果を100件取得する
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● PHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事