そこでwp_cronを監視するプラグインをいくつか試しましたが、一番よかったと思うのがWP-Crontrolでした。
気に入っている点として、管理画面上から即時実行ができる点があります。
実行結果が間違っていないかをすぐに確認できますし、Cron登録済みの処理をすぐ実行したいときにも重宝します。
Product Advertising API(以下AmazonAPI)はAmazonから商品データを取得することができるAPIです。
AmazonからデータをWordPressに投稿するコードを書きましたのでよかったら参考にしてみてください。
※以下全部functions.phpに書いてください。
ADs
まずはAmazonAPIで必ず必要になるアクセスキーやシークレットキーなどを定義します。
実際のキーの取得やアカウント登録などの手順についてはAmazon Webサービス入門 サービス利用の準備の解説が詳しいです。
1 2 3 4 5 |
//Amazon共通の定数 define('AF','nets0f-22'); //トラッキング define('AC','AAAAAAAAAAAAAAAA'); //アクセスキー(架空のものです) define('SEC','abcdefghijklmnopqrstuvwxyz'); //シークレットキー(架空のものです) define('URL','http://ecs.amazonaws.jp/onca/xml'); //リクエスト先のURL |
次は商品データ取得の際に必要となるfunctionの定義です。都度ベタに書いてもいいですがあとあと大変な目にあいます。
そろそろclass覚えないと。。。。
絶対必要なのはget_key()というfunctionで、ここでAmazonAPIに必要なタイムスタンプによる認証キーを生成しています。
認証(Timestamp及びSignature)の項が詳しいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
//認証取得用function function urlencode_rfc3986($str) { return str_replace('%7E', '~', rawurlencode($str)); } function get_key($param){ ksort($param); $canonical_string = ''; foreach ($param as $k => $v) { $canonical_string .= '&'.urlencode_rfc3986($k).'='.urlencode_rfc3986($v); } $canonical_string = substr($canonical_string, 1); $parsed_url = parse_url(URL); $string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}"; $signature = base64_encode(hash_hmac('sha256', $string_to_sign, SEC, true)); // 返り値のURLにアクセスするとXMLが取得できます。 return URL.'?'.$canonical_string.'&Signature='.urlencode_rfc3986($signature); } //画像をサーバに保存するfunction //URLを投げたら指定したディレクトリに保存するだけ。。。。 function dl_image($url){ $tempimg = file_get_contents($url); file_put_contents(WP_CONTENT_DIR.'/upload/'.basename($url),$tempimg); unset($tempimg); return WP_CONTENT_DIR.'/upload/'.basename($url); } |
ここまでで下準備が終わりましたので、実際にAmazonAPIにアクセスして商品データを取得します。
以下の例はAmazon内のDVDカテゴリの中のアニメカテゴリから新着順に商品を取得する例です。
なお、実際の実行はCronに任せますのでfunctionの定義だけでまだ実行はされません。
カスタムフィールドにどの値を持つか、本文はどうするかなどは適宜カスタマイズしてみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
//ここから実際の取得処理------------------------------------------ //取得処理はwp_cronで動かしますのでadd_actionは不要です。 function get_amazon(){ $ct = array( '1' => '562020' //WP上のカテゴリID => Amazon上のカテゴリNo ); //ページカウンター //1ページずつ取っていきます。どこまで取得できたかをget_optionで保持している if(get_option('count')){ $i = get_option('count'); } else { $i = 1; add_option('count',1); } foreach($ct as $key=>$val){ //Amazonで必要なパラメーター類 $param = array( 'Service' => 'AWSECommerceService', 'AWSAccessKeyId' => AC, 'Operation' => 'ItemSearch', 'AssociateTag' => AF, 'ResponseGroup' => 'ItemAttributes,Images,Reviews', 'SearchIndex' => 'DVD', 'BrowseNode' => $val, 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'), 'ItemPage' => $i ); //先に定義した認証パラメータ付きURLを生成 $recurl = get_key($param); //ページカウントを進める //XML取得の途中で落ちてもいいようにforeach入る前にしてますがforeach後のほうが自然かも update_option('count',$i + 1); //XML取得 $xml = simplexml_load_file($recurl); foreach($xml->Items->Item as $key2=>$val2){ $actarray = array(); foreach($val2->ItemAttributes->Actor as $act){ $actarray[] = (String)$act; } //ここで記事として投稿処理を行う //ページスラッグがEANコード(ISBN的なものだと思われる)、タグをキャストとして投稿していますが適宜カスタムフィールドや本文などにしてもいい。 $postid = wp_insert_post(array( 'post_status' => 'publish', 'post_category' => array($key), 'post_title' => $val2->ItemAttributes->Title, 'post_name' => $val2->ItemAttributes->EAN, 'tags_input' => $actarray )); //重複チェック //同じ商品を取ってしまった場合、EANが同じになるので末尾に「-2」などと付加される。その「-」があれば一回投稿した記事を削除する。 //なお、無条件で「-」入りだと削除しているのでEAN以外をpost_nameにしていると間違って削除されるおそれがあります。 $temppost = get_page($postid); if(strpos($temppost->post_name, '-') === true){ wp_delete_post($postid); } else { //カスタムフィールドの付加 //商品URLや画像URLに加えて最終更新日としてtime()を追加している。理由は後述。 if($postid){ add_post_meta($postid,'DetailPageURL',(String)$val2->DetailPageURL,true); add_post_meta($postid,'SmallImage',(Array)$val2->SmallImage,true); add_post_meta($postid,'MediumImage',(Array)$val2->MediumImage,true); add_post_meta($postid,'LargeImage',(Array)$val2->LargeImage,true); add_post_meta($postid,'IFrameURL',(String)$val2->CustomerReviews->IFrameURL,true); add_post_meta($postid,'LastUpdate',(String)time(),true); //画像をローカルに保存する $smalimg = $val2->SmallImage->URL; $smalimg_local = dl_image($smalimg); $midimg = $val2->MediumImage->URL; $midimg_local = dl_image($midimg); $largeimg = $val2->LargeImage->URL; $largeimg_local = dl_image($largeimg); } } }//end foreach xml }//end foreach }//Amazonからの取得処理ここまで |
上記の処理を手動で走らせたり連続で走らせるとすぐにサーバが落ちたりAPIへのアクセスがブロックされたりしてしまいます。
そこでCron(wp_cron)を使って定期的に自動実行させます。
AmazonAPIの利用規約では1時間2000リクエストとなっていますので、それを超えないように注意してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//Cronの設定--------------------------------------------------------- //デフォルトのdailyやweeklyだけだと使い勝手が悪いのでいくつか足しておく //このcron_schedulesとwp_schedule_eventはテンプレ的にこのままでいいでしょう。 add_filter('cron_schedules','cron_add'); function cron_add($schedules){ $schedules['90min'] = array( 'interval' => 5400, 'display' => __( '90min' ) ); $schedules['100min'] = array( 'interval' => 6000, 'display' => __( '100min' ) ); $schedules['120min'] = array( 'interval' => 7200, 'display' => __( '120min' ) ); return $schedules; } //Cronに上記のget_amazon()を登録する //90分単位で動作します。 add_action('cron_for_amazon', 'get_amazon'); function my_activation() { if ( !wp_next_scheduled( 'cron_for_amazon' ) ) { wp_schedule_event(time(), '90min', 'cron_for_amazon'); } } add_action('wp', 'my_activation'); |
AmazonAPIの規約では、商品データをローカル(というか自分のサーバ)に保持することは許可されていますが、24時間以上保持することが禁止されています。
そこでデータ取得時に現在時刻をカスタムフィールドに保存していましたので、その時刻と現在時刻の差が24時間以上であれば再度商品取得処理を行うという処理を加えます。
これはCronではなくshutdownにフックしています。
誰かがアクセスしてそのときが24時間を超えていれば更新する、という仕組みです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
//ここからは商品データアップデート処理------------------------------------------ //Amazonは規約で24時間以上のキャッシュ保存が認められません。そこで前述のカスタムフィールドに加えている「LastUpdate」を見て、24時間が経過している場合は更新処理を行います。 function update_amazon(){ if(is_single()){ global $post; //LastUpdateと現在時刻の差が「60秒*60分*24時間」以上なら処理する if($post->LastUpdate < (time() - 86400 )){ $param = array( 'Service' => 'AWSECommerceService', 'AWSAccessKeyId' => AC, 'Operation' => 'ItemLookup', 'AssociateTag' => AF, 'ResponseGroup' => 'ItemAttributes,Images,Reviews', 'IdType' => 'EAN', 'SearchIndex' => 'DVD', 'ItemId' => $post->post_name, //EANさえあれば商品は引っ張れる 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'), ); $recurl = get_key($param); $xml = simplexml_load_file($recurl); if($xml->Items->Item){ foreach($xml->Items->Item as $val2){ update_post_meta($postid,'DetailPageURL',(String)$val2->DetailPageURL); update_post_meta($postid,'SmallImage',(Array)$val2->SmallImage); update_post_meta($postid,'MediumImage',(Array)$val2->MediumImage); update_post_meta($postid,'LargeImage',(Array)$val2->LargeImage); update_post_meta($postid,'IFrameURL',(String)$val2->CustomerReviews->IFrameURL); update_post_meta($postid,'LastUpdate',(String)time()); //画像の差し替え //引数無しfile_put_contentsなので上書きされます $smalimg = $val2->SmallImage->URL; $smalimg_local = dl_image($smalimg); $midimg = $val2->MediumImage->URL; $midimg_local = dl_image($midimg); $largeimg = $val2->LargeImage->URL; $largeimg_local = dl_image($largeimg); } } } } }//func end //shutdownにフックすることで見る人にも優しい(はず) add_action('shutdown','update_amazon'); |
コードをまとめたものはgistに上げてます。
気に入っている点として、管理画面上から即時実行ができる点があります。
実行結果が間違っていないかをすぐに確認できますし、Cron登録済みの処理をすぐ実行したいときにも重宝します。
単純にAmazonからデータを取得してアフィリエイトサイトに仕立てたとしても、まず儲からないでしょう。そのようなクローンサイトのようなものはGoogleからも嫌われ、ユーザーにとってもメリットがありません。
データを取得し、何らかの加工をして提供する必要があると思います。
たとえば顔認識APIを使えば楽モになりますし、楽天などからも商品情報を取って多角的に比較できる情報サイトにしてもいいでしょう。画像の色を分析し、色で検索できる商品サイトなども面白いかもしれません。
せっかく大量の商品データを扱うことができるのですから(しかもAmazonだけでなく、楽天もあるしYahoo!もあるし)、一捻り加えて面白いサイトをつくってみてください。
APIを使うサイトなら直接APIを呼び出して都度ページを生成したり、自前でキャッシュ処理を書けばWordPressを使う必要はありません。
ですが以下の様なメリットがあると思い、WordPressに投稿するというかたちを取っています。
・サイト独自のコメントや評価機能をつけたい
→コメントは標準装備です。評価機能はプラグインがいろいろ。
・会員制サイトにして内輪で盛り上がりたい
→会員機能も標準装備です。ソーシャルログインもプラグインを使えば簡単です。
・キャッシュ処理が難しい
→記事にしてしまえばそれすなわちキャッシュとなります(アップデートのための処理は必須ですが)
・自分で組んだら遅い、重い
→WordPress高速化のノウハウは多くの方が実践されています。それがそのまま使えます。
WordPressにはこういう使い方もあるということで。。。。
何かの参考になれば幸いです。
ADs
コメントはまだありません。