Created
April 5, 2013 13:24
-
-
Save woodroots/5319238 to your computer and use it in GitHub Desktop.
AmazonからAPIを使って商品データを取得し、WordPressに投稿する方法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//Amazon共通の定数 | |
define('AF','nets0f-22'); //トラッキング | |
define('AC','AAAAAAAAAAAAAAAA'); //アクセスキー | |
define('SEC','abcdefghijklmnopqrstuvwxyz'); //シークレットキー | |
define('URL','http://ecs.amazonaws.jp/onca/xml'); //リクエスト先のURL | |
//認証取得用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); | |
} | |
//ここから実際の取得処理------------------------------------------ | |
//取得処理は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からの取得処理ここまで | |
//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'); | |
//ここからは商品データアップデート処理------------------------------------------ | |
//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'); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment