前回の記事ではYouTube APIをブラウザから手動で実行し、データが得られる仕組みと具体的な使用方法をご紹介しました。今回からはPHPのプログラムによって「データ取得 → DB接続 → 記事データ生成」という動画まとめサイトの核になる仕組みを解説していきます。
基本的にある程度web制作を理解している前提で記述するつもりですので、レンサバの設定やPHPでHello worldとかはやらない予定です。可能な限り丁寧に解説しますが、不明な部分はググりながら読み進めて頂けると助かります。どうしても分からない部分はコメントして頂ければ、僕の分かる範囲で答えようとは思います。
ワードプレスは各自インストールしておいて下さい、ググれば資料はたくさんありますので困る事はないと思います。
レンサバはmixhostを使用していますのでそれに準じた解説になるかと思います。ファイルの場所とか設定はそれぞれ使っている環境に合わせて調整して下さい。
プログラミングの環境を準備
レンサバにプログラミングをするための環境を作って行きましょう。必要なフォルダやファイルを作成し、それらに対して自分以外の人間に見られないようにアクセス制限を掛けていきます。すでに実行環境が整っている方は、次項まで読み飛ばして下さい。
必要な動画データの確認
まずは設計した動画まとめサイトにはどんなデータ必要なのか確認して行きましょう、今回は僕の大好きな犬の動画まとめサイトを作ろうと思います。犬種毎にカテゴリを分けて見れるようにして、内容毎にタグも付けたいです。
この内容であれば動画単体の詳細データがあれば足りそうですので、前回ご紹介したsearchリソースのキーワード検索を使って必要なデータを抽出したいと思います。キーワードとペット動画のカテゴリを両方指定する事で、ノイズとなる犬の動画と関係ないデータをなるべく入れないようにします。
動画カテゴリは常に最新のデータを調べられるようにツールを作りました。見た目は普通の一覧表ですがYouTube APIを毎日自動実行してるので、常に新鮮な情報を得られます。
具体的に取得する必要のあるデータは「動画ID・動画公開日・チャンネルID・動画タイトル・動画説明・サムネイルURL・タグ・再生時間・埋め込みコード」くらいあれば十分なんじゃないかと思います。作ってる途中で足りないデータが出てきたら随時追加すればオッケーです。
ワードプレスとは別の場所にフォルダを準備
まずはプログラムを書くための土台の準備をします。ワードプレスをサーバーにインストールすると、自動でフォルダが作成されますが、オリジナルのPHPファイルはその中に保存しないでください。ファイルの場所が分かりづらくなる原因にもなりますし、ワードプレスの自動アップデートやアンインストールによって消えてしまう可能性もあります。
上記の画像はmixhostでのファイルマネージャー画面ですが、どのレンサバも似たような画面だと思うので参考にはなると思います。今回はpublic_htmlの直下に「diy-programming」というフォルダを作成し、この中に自作したPHPファイルを作っていきます。参考にされる方はセキュリティ的に各自フォルダ名を変更して下さい。
今後いくつもプログラムを作って行くので、煩雑にならないように自作のプログラムはフォルダを分けてまとめて管理しておきましょう。
PHPファイルとfunctionファイルを準備
先ほど作ったフォルダにプログラムを記述するPHPファイルと、ユーザ定義関数を保存するfunctionファイルを作っておきましょう。このfunctionファイルもワードプレスで用意されている物とは別に準備して下さい。テーマを構成する既存のユーザー定義関数を誤って改変してしまった場合、ワードプレスが動かなくなってしまう可能性もありますので、自作するファイルはすべて別管理にしておく方が安全かと思います。
今回は「public_html/programming」フォルダに「00_youtube_api_movie_info.php」と「functions.php」というファイルを作成しました。それぞれのファイルを開いて実際にプログラムを書いていきます。ファイル名に関しては自分が分かりやすければ良いと思いますが、ファイル名の頭には数字で00~99と連番を振っておくと、昇順や降順でファイルがキチンと並んでくれるのでオススメです。
今回記述するプログラムはYouTube APIのデータを取得しデータベースへ保存する内部処理なので、自分以外アクセスできないようにファイルのパーミッションを700へと変更して下さい。
この設定は外部からファイルへのアクセスや実行を禁止するための重要な設定ですので忘れずに行いましょう。逆に複数人で一つのフォルダやファイルを読み書きする場合は、パーミッションを開放しないと作業できません。DIYの僕たちには必要なシーンは無いと思いますが一応覚えておきましょう。
プログラム実行用のドメインを割り当て
ここまででフォルダとファイルの作成は完了しましたが、このままでは表示用のドメインが割り当てられていないためブラウザ上でPHPを動作させる事ができません。なのでプログラム実行用のサブドメインを作成し、作成したフォルダに割り当てましょう。
この設定を行う事で「/public_html/diy-programming」の中身に「https://exe.diy-programming.site」としてブラウザから表示できるようになります、作成したサブドメインからファイルを開けるか試してみて下さい。僕の場合は「https://exe.diy-programming.site/00_youtube_api_movie_info.php」にブラウザから実行できるようになっているハズです。ただしこのままでは、アクセス制限を設定しないと誰でもファイルを実行できてしまうので注意して下さい。
PHPプログラムの実行にはいくつか方法がありまして、例えばローカルにXamppをインストールしてwebと切り離した環境で実行テストを行ったり、PHPファイルの実行テストを行えるサービスなんてのもあります。僕はいつもディレクトリにPHP実行用のサブドメインを設定する方法で実行テストを行っています。自作したファイルをそのままブラウザのお気に入りに入れておけるので便利なんですよね。
このサブドメインはPHPの実行テストが終わった段階で削除する事をオススメします。最終的に作成したPHPファイルは「Cron」と呼ばれるファイルを指定した日時で自動実行する機能に任せる事になります。なので、今回作成した「https://exe.diy-programming.site」はツールが完成した後は不要になります。アクセスを制限していると言っても、プログラムをネット上に公開している事には変わりないので速やかに閉鎖しましょう。プログラムを修正したい時は、同じ手順でまたサブドメインを割り当ててやれば使えるようになります。手間ですが誰かに悪さをされたくなければ対策しておきましょう。
ディレクトリプライバシーを設定しアクセスを制限
セキュリティの設定はこれで最後です、先ほどサブドメインを割り当てたディレクトリにアクセス制限を行いましょう。これでプロブラム実行用の「https://exe.diy-programming.site」にはログインしなければPHPファイルの実行ができなくなります。当然ですが、設定したユーザー名とパスワードは忘れないように気を付けて下さいね。
ディレクトリへのアクセス制限はその下層のファイルにも引き継がれます。例えば、最上位の「public_html」にアクセス制限を掛けると、その下層にあるすべてのファイルはログインしなければ閲覧する事はできなくなります。つまり、個々のファイルに1個ずつ設定する必要はないという事です。
mixhostではディレクトリプライバシーと呼ばれる機能で簡単にアクセス制限を行う事ができますが、他のレンサバの場合は、.htaccessファイルを自作して設定しなければならない所もあるかもしれません。各自お使いのレンサバのヘルプを確認して設定して下さい。
PHPからAPIを実行する
基本的には前回の記事で手動で行っていた部分を、PHPのプログラムで実行するという内容です。YouTube APIを呼び出すリクエストURLの理解も必要になってくるので、このページから読み始めたという方はこちらの記事にも目を通しておく事をオススメします。
普段プログラミングをやらない方はPHPの入門書を手元に置いておくと、スムーズに作業が進められると思います。
変数を連結してリクエストURLを作成
それでは準備した「https://exe.diy-programming.site/00_youtube_api_movie_info.php」にプログラムを書いて行きましょう。まずはYouTube APIを呼び出すリクエストURLを作成します。前回の記事では手動でパラメータを設定しリクエストURLを作っていましたが、パラメータの値を変えるだけでリクエストURLを出力できるプログラムを作ってみます。
<?php
$dog_category = array('アメリカンコッカースパニエル', 'コーギー', 'ゴールデンレトリバー');
foreach($dog_category as $value){
$option = array(
//apiキー
'key' => '【APIキー】',
//必須パラメータ:id or snippet
'part' => 'snippet',
//フィルタ:最大1個まで
'forContentOwner' => null,
'forMine' => null,
'relatedToVideoId' => null,
//省略可能なパラメータ
'channelId' => null,
'channelType' => null,
'eventType' => null,
'maxResults' => '5',
'onBehalfOfContentOwner' => null,
'order' => 'relevance',
'pageToken' => null,
'publishedAfter' => null,
'publishedBefore' => null,
'q' => $value,
'regionCode' => 'JP',
'safeSearch' => null,
'topicId' => null,
'type' => 'video',
'videoCaption' => null,
'videoCategoryId' => '15',
'videoDefinition' => null,
'videoDimension' => null,
'videoDuration' => null,
'videoEmbeddable' => null,
'videoLicense' => null,
'videoSyndicated' => null,
'videoType' => null
);
$search_url = "https://www.googleapis.com/youtube/v3/search?".http_build_query($option, '&');
$decode_search_url = array(htmlspecialchars_decode( $search_url ));
print_r($decode_search_url);
}
?>
$option配列にリクエストURLの各種パラメータを一通りぶち込んで、http_build_query関数でURLにくっ付けました。APIキーは忘れずに置き換えて下さい。
犬種毎にカテゴリを分けようと思っているのですが、動画データ側には犬種カテゴリまでは用意されてないので、具体的な犬種名でキーワード検索するようにしました。例えばコーギーというキーワードでヒットした動画データに一律コーギーというカテゴリを後で付与してデータベースへ渡そうと思います。$dog_category配列に犬種を追加すれば対応したリクエストURLが出力されます。
36行目の「’videoCategoryId’ => ’15’,」は動画カテゴリの「ペットと動物」を指定しています。動画カテゴリIDの調べ方はこちらの記事で紹介してします。
このコードを実行するとこんな感じでリクエストURLが出力されます。
はい、これで3種類の犬種に限定して動画を取得するリクエストURLがPHPプログラムから出力されました。このリクエストURLをブラウザにコピペしてYouTube APIが問題なく動作するか確認して下さい。問題がなければ成功です、結構簡単でしたよね。今回のは3件のリクエストURLがくっついちゃってるので、ブラウザにコピペする時はちゃんと切り分けて下さいね。
CURLでYouTube APIを実行する
今度は作成したリクエストURLをPHPプログラムで実行してみましょう。今回はCURLと呼ばれる関数を使って、YouTube APIからデータを取得します。
データを取得するにはfile_get_contentsという関数もありますが、僕はCURLをオススメします。理由はCURLの方が制御に関する多くのパラメータを設定することができて非常に便利なんです。
僕が1番大きな違いだと思うのは、リクエストを複数同時に実行できる並列処理と言う機能です。例えば1件処理するのに1秒かかるリクエストを100件処理しなければならない場合、すべての処理が終わるまで100秒掛かります。しかしCURLの場合は100件のリクエストを同時に実行することができるため、必要な時間は1秒で済みます。
ただしこの機能にもデメリットがあって、通常1件ずつ処理するところを100件まとめてゴリゴリと処理するのでメモリを100倍消費します。安いレンタルサーバーでは割り当てられているメモリも少ないので、使用する際はメモリの余力に注意しましょう。最悪の場合はサーバーのダウンにもつながる危険性がありますので、慎重に扱ってください。
このCURLは記述が少々長くなりますし、他のAPIデータを取得する際に何度も使い回す事になるので、functionファイルにユーザー定義関数として記述しておきましょう。こうやって準備しておけば今後は1行のプログラムで、CURLを呼び出せるようになるので非常に便利です。
というワケで、CURLの実行をユーザー定義関数としてこんな感じで書いてみました。今回のコードはこちらの記事を参考にさせて頂きました、ありがとうございますm(_ _)m
<?php
// youtube APIから動画情報を取得する
function youtube_api_get($decode_search_url){
$api_content = array();
$TIMEOUT = 40;
$mh = curl_multi_init();
foreach ($decode_search_url as $u) {
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $u,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $TIMEOUT,
CURLOPT_CONNECTTIMEOUT => $TIMEOUT,
));
curl_multi_add_handle($mh, $ch);
}
do {
$stat = curl_multi_exec($mh, $running);
} while ($stat === CURLM_CALL_MULTI_PERFORM);
if ( ! $running || $stat !== CURLM_OK) {
throw new RuntimeException('リクエストが開始出来なかった。マルチリクエスト内のどれか、URLの設定がおかしいのでは?');
}
do switch (curl_multi_select($mh, $TIMEOUT)) {
case -1:
usleep(5);
do {
$stat = curl_multi_exec($mh, $running);
} while ($stat === CURLM_CALL_MULTI_PERFORM);
continue 2;
case 0:
continue 2;
default:
do {
$stat = curl_multi_exec($mh, $running);
} while ($stat === CURLM_CALL_MULTI_PERFORM);
do if ($raised = curl_multi_info_read($mh, $remains)) {
$info = curl_getinfo($raised['handle']);
echo "$info[url]: $info[http_code]: $info[total_time]\n";
$response = curl_multi_getcontent($raised['handle']);
if ($response === false) {
echo 'ERROR!!!', PHP_EOL;
} else {
$response_json = json_decode($response,true);
array_push($api_content, $response_json);
}
curl_multi_remove_handle($mh, $raised['handle']);
curl_close($raised['handle']);
} while ($remains);
} while ($running);
echo 'finished', PHP_EOL;
curl_multi_close($mh);
return $api_content;
}
便利な関数なんで理解する事が望ましいですが、とりあえず「https://exe.diy-programming.site/functions.php」にコピペしておけば使えるようになります。
お次は「00_youtube_api_movie_info.php」から今作った「functions.php」を呼び出して、ユーザー定義関数を使用できるようにコードを改変しましょう。数行追加するだけなんで簡単です。こんな風になります。
<?php
include(dirname(__FILE__) . '/functions.php');
$dog_category = array('アメリカンコッカースパニエル', 'コーギー', 'ゴールデンレトリバー');
foreach($dog_category as $value){
$option = array(
//apiキー
'key' => '【APIキー】',
//必須パラメータ:id or snippet
'part' => 'snippet',
//フィルタ:最大1個まで
'forContentOwner' => null,
'forMine' => null,
'relatedToVideoId' => null,
//省略可能なパラメータ
'channelId' => null,
'channelType' => null,
'eventType' => null,
'maxResults' => '5',
'onBehalfOfContentOwner' => null,
'order' => 'relevance',
'pageToken' => null,
'publishedAfter' => null,
'publishedBefore' => null,
'q' => $value,
'regionCode' => 'JP',
'safeSearch' => null,
'topicId' => null,
'type' => 'video',
'videoCaption' => null,
'videoCategoryId' => '15',
'videoDefinition' => null,
'videoDimension' => null,
'videoDuration' => null,
'videoEmbeddable' => null,
'videoLicense' => null,
'videoSyndicated' => null,
'videoType' => null
);
$search_url = "https://www.googleapis.com/youtube/v3/search?".http_build_query($option, '&');
$decode_search_url = array(htmlspecialchars_decode( $search_url ));
$api_content = youtube_api_get($decode_search_url);
print_r($api_content);
}
?>
先ほど作ったリクエストURLを出力するPHPプログラムを3行だけ修正しました。
まずは3行目に「include(dirname(__FILE__) . ‘/functions.php’);」と追加し、作成したfunctionsファイルを利用できるようにしています。include関数は外部のファイルを読み込む関数でユーザー定義関数を使用する場合は、このようにパスを指定するパターンが必ず出て来るので覚えておきましょう。
52行目には「$api_content = youtube_api_get($decode_search_url);」を追加し、リクエストURLをfunctionsファイル内で自作したyoutube_api_get();へ送って、出力された動画データを$api_content内に格納しています。ユーザー定義関数が良く分からんという方はこちらの記事が分かりやすいです。
54行目のprint_rはリクエストURLを表示していましたが、$decode_search_url → $api_contentへ変更し、取得したAPIデータを表示するようにしました。
そしてこのプログラムを実行すると、こんな感じにデータが返ってきます。
「00_youtube_api_movie_info.php」を実行して上のように動画データが表示されれば成功です。これでPHPからYouTube APIにリクエストURLを送り動画データを取得する事ができました。しかし、このままでは改行や余白がない状態で表示されすごく見にくいです。なので、右クリックして「ページのソースを表示」を押せばキレイに体系化されたデータとしてみる事ができます。
まとめ&次回予告
今回は「リクエストURLの生成→CURLでYouTube APIのデータを取得」という所まで解説しました。実行手順やコピペで使えるモノが多かったので、それほど難しくはなかったと思います。
そろそろ動画まとめサイトの枠組みが見えて来ましたね、次回はワードプレスの記事データベースへ今回取得した動画データをぶち込んで、記事データを自動生成する所まで解説したいと思います。一気にそれっぽくなりますんで、お楽しみに~☆
分からない事や依頼があれば受け付けてますんでお問い合わせからご連絡下さいm(_ _)m
youtubeの動画を自動で投稿するwpプラグイン完成!
当サイトで解説しているyoutube動画まとめサイト作成のノウハウを元に、誰でも簡単に動画まとめサイトが作れるwpプラグインを作りました、使用感は下記の動画をご覧ください!
こんな感じで簡単な設定だけで記事が自動投稿される動画まとめサイトを作れます、youtunerの詳しい解説は下記の記事で解説しています。
個人開発プログラマーを応援するメンバーシップを始めました('ω')ノ
質問・要望・共同作業など、みんなのやりたい事をスマイルがお手伝いします。立ち上げたばかりでよく分かってないので、とりあえず何でもありやってみます。
コメント
手順通りにしましたが出来ないです。
「00_youtube_api_movie_info.php」と「functions.php」のコピペでもダメでした。
コメントありがとうございます(‘ω’)ノ
>手順通りにしましたが出来ないです。「00_youtube_api_movie_info.php」と「functions.php」のコピペでもダメでした。
僕の環境では記事の手順で動く事は確認してますんで、何か違いがあるのかもしれませんね。
もう少し症状を詳しく説明頂ければ、何かしらアドバイスできる事もあると思います。
よろしくお願いしますm(_ _)m
【変数を連結してリクエストURLを作成】
この部分でサンプル通りの出力が出来ていないのですが、こちらは成功してますでしょうか?
Array
(
[0] => https://www.googleapis.com/youtube/v3/search?key=APIキー&part=snippet&maxResults=5&order=relevance&q=%E3%82%B3%E3%83%BC%E3%82%AE%E3%83%BC®ionCode=JP&type=video&videoCategoryId=15
)
URLをブラウザにコピペすると成功しているようにもみえます。
【CURLでYouTube APIを実行する】
Fatal error: Maximum execution time of 30 seconds exceeded in /ファイルパス/functions.php on line 28
上記のようなエラーが出ます。
お手数ですが、ご教示頂けたら幸いです。
>この部分でサンプル通りの出力が出来ていないのですが、こちらは成功してますでしょうか?
繰り返しになりますが、当サイトで掲載しているサンプルはすべて実行確認を行ってます。僕の環境での実行結果は下記の通りです。
———————————
Array
(
[0] => https://www.googleapis.com/youtube/v3/search?key=%E3%80%90API%E3%82%AD%E3%83%BC%E3%80%91&part=snippet&maxResults=5&order=relevance&q=%E3%82%A2%E3%83%A1%E3%83%AA%E3%82%AB%E3%83%B3%E3%82%B3%E3%83%83%E3%82%AB%E3%83%BC%E3%82%B9%E3%83%91%E3%83%8B%E3%82%A8%E3%83%AB®ionCode=JP&type=video&videoCategoryId=15
)
Array
(
[0] => https://www.googleapis.com/youtube/v3/search?key=%E3%80%90API%E3%82%AD%E3%83%BC%E3%80%91&part=snippet&maxResults=5&order=relevance&q=%E3%82%B3%E3%83%BC%E3%82%AE%E3%83%BC®ionCode=JP&type=video&videoCategoryId=15
)
Array
(
[0] => https://www.googleapis.com/youtube/v3/search?key=%E3%80%90API%E3%82%AD%E3%83%BC%E3%80%91&part=snippet&maxResults=5&order=relevance&q=%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%87%E3%83%B3%E3%83%AC%E3%83%88%E3%83%AA%E3%83%90%E3%83%BC®ionCode=JP&type=video&videoCategoryId=15
——————————
>上記のようなエラーが出ます。
普通にタイムアウトエラーみたいですね。youtube APIキーのホワイトリスト設定でIPアドレスを制限してたりしませんか??もしくはAPIキーの入力間違いとかないですかね??
このサンプルコードは処理に時間の掛かる物ではないので、通常は2-3秒で終わると思います。書き換える部分はyoutubeAPI周りくらいしかないので、確認してみて下さい。
よろしくお願いしますm(_ _)m
お返事ありがとうございます。
【変数を連結してリクエストURLを作成】
こちらは実行確認できました。
functions.phpが絡むと動作しなくなります。
>youtube APIキーのホワイトリスト設定でIPアドレスを制限してたりしませんか??もしくはAPIキーの入力間違い
制限などはかけてません。APIキーも正しいのを入れています。
環境はさくらインターネットのサーバーです。サーバー側の設定の問題でしょうか?
>環境はさくらインターネットのサーバーです。サーバー側の設定の問題でしょうか?
さくらは使った事がないのでわかりませんが、もしかするとcurlがインストールされてなかったりしますか??
その場合はAPIのエンドポイントにアクセスする際、file_get_contents()とかでも代用可能なので書き換えてみて下さい(‘ω’)ノ
よろしくお願いしますm(_ _)m