読者です 読者をやめる 読者になる 読者になる

試される大地から

furaiboが送る技術ブログ。プログラミングのTipsなど書いていきます。

AmazonからCDのジャケット画像を取得するPythonスクリプト


Amazonから指定した楽曲CDのジャケット画像を探してくるLinux向けのPythonスクリプトを書いてみた。画像取得にはProduct Advertising APIを利用。これを使うにはAWSAmazonアソシエイトのアカウントが必要なので、ややハードルが高いかも。



bottlenoseと呼ばれるライブラリを利用してAmazon APIを飛ばしたが、知らないことが多かったため、ややつまづいた。AWSアクセスキー・秘密鍵などを間違えて入力すると403エラーになって、なんのこっちゃってなった。



さらに、Pythonエンコーディングや端末でのキーボード入力でも詰まりまくった。特に、setdefaultencoding関数ではsysパッケージをリロードしないとエラーが発生するなど謎の挙動で戸惑った。やっぱりPython2.xはRubyと違って日本語のエンコーディング周りで難が多いようだ。しかしなんとか完成することが出来た。まだ十分にブラッシュアップしていないので使い勝手がもう一つなのはご愛嬌。



スクリプトを使う前にはパッケージインストールが必要です。また、スクリプトでディレクトリの作成や権限の変更を行うため、sudoコマンドの利用あるいはroot権限での実行が必要となります。ご注意下さい。




CentOS(Redhat系)の場合

#!/bin/sh
#
# sudoまたはroot権限で実行すること
#

# パッケージインストール
yum -y install python-setuptools

# setuptools 0.8
wget https://bitbucket.org/pypa/setuptools/raw/0.8/ez_setup.py
python ez_setup.py --user

# pip
easy_install pip
pip install python-amazon-product-api
pip install bottlenose
pip install beautifulsoup

Ubuntu(Debian系)の場合

#!/bin/bash
#
# sudoまたはroot権限で実行すること
#

# パッケージインストール
# setuptools 0.8
wget https://bitbucket.org/pypa/setuptools/raw/0.8/ez_setup.py
python ez_setup.py --user

# pip
easy_install pip
pip install python-amazon-product-api
pip install bottlenose
pip install beautifulsoup



スクリプトソースコードは以下です。


#!/usr/bin/python 
#-*- coding:utf-8 -*-

# パッケージのimport
import os
import sys
import re
import urllib2
import bottlenose
from datetime import datetime
from BeautifulSoup import BeautifulStoneSoup

# エラー対策
# setdefaultencoding利用時に発生する以下のエラーを回避する
# AttributeError: 'module' object has no attribute 'setdefaultencoding'
reload(sys)

# デフォルトエンコーディングの変更
# ポータビリティが低下するため本来は非推奨
sys.setdefaultencoding('utf-8')


# 関数定義
# タグを取り除く関数
def remove_tag(string):
	p = re.compile("<.*?>(.*?)</.*?>")
	m = p.search(string)
	return m.group(1)



# 指定URLの画像をダウンロードする関数
def image_download(img_url, output):

	# HTTPリクエスト
	opener = urllib2.build_opener()
	req = urllib2.Request(img_url, headers={'User-Agent' : "Magic Browser"})

	# もし同名の画像ファイルが存在するならば、上書きは行わない
	if not os.path.exists(output):
		img_file = open(output, 'wb')
		img_file.write(opener.open(req).read())
		img_file.close()



# AmazonからAPIで商品画像のURLを取得する関数
def get_amazon_image_URLs(aws_key, aws_secret, associate_id, searchindex, artist, keywords):
	
	# API
	api = bottlenose.Amazon(aws_key, aws_secret, associate_id, Region="JP")
	xml = api.ItemSearch(SearchIndex=searchindex, Artist=artist, Keywords=keywords, ResponseGroup="Images")

	# XMLから情報を取り出す
	soup = BeautifulStoneSoup(xml)

	# 大画像のURLの配列を取得
	return_urls = []
	urls = soup.findAll('url')
	patterns = ["_SL30_", "_SL75_", "_SL110_", "_SL160_"]
	for url in urls:
		# URLが縮小画像のものかどうかのフラグ
		flag = True
		
		# soup型から文字列型に変換する
		url = str(url)

		# タグを取り除く
		url = remove_tag(url)

		# 縮小画像を取り除くためのマッチング
		for i in patterns:
			if url.find(i) > -1:
				flag = False
				break
		if flag == True:
			return_urls.append(url)


	# 重複要素を除去したリストを得る
	return_urls = list(set(return_urls))

	# 戻り値
	return return_urls
		


# URLのリストから画像をダウンロードする関数
def download_all_images(urls, dl_path):

	# 変数
	count = 0		# ダウンロード済みの画像の数
	limit = 20		# 画像の数の上限

	# 正規表現
	pat_img_name = re.compile('.+/(.*)')

	# 日時・時刻を取得
	d = datetime.now()
	title = d.strftime('%Y%m%d%H%M%S')

	# ディレクトリ名
	dirname = "%s/%s"%(dl_path, title)

	# ディレクトリを作成する
	os.mkdir(dirname)

	# 権限を付与する
	os.chmod(dirname, 0777)

	# 画像をダウンロードする
	for i in urls:
		# 画像の数の上限を越えた場合は中止
		if count > limit:
			break

		# 画像名を決定し、URL先の画像のダウンロードを行う
		m = pat_img_name.search(i)
		filename = m.group(1)
		output = "%s/%s"%(dirname, filename)
		image_download(i, output)

		# 権限を付与する
		os.chmod(output, 0777)

		# ダウンロード済みの画像の数をカウント
		count += 1



# main関数
if __name__ == '__main__':

	# 画像の出力先
	dl_path = "./downloads"

	# AWSアクセスキー・秘密鍵等の情報
	aws_key      = "[あなたのAWSアクセスキー]"		# AWSアクセスキー
	aws_secret   = "[あなたのAWS秘密鍵]"			# AWS秘密鍵
	associate_id = "[あなたのAmazonアソシエイトID]"		# AmazonアソシエイトID
	
	# Amazonから取得したい商品の情報
	searchindex  = "Music"			# ジャンルの指定
	artist       = ""			# 歌手・アーティスト
	keywords     = ""			# キーワード

	# 端末から入力を受け付ける
	# アーティスト名を入力
	print "アーティスト名を入力してください"
	sys.stdout.write("アーティスト名 : ")
	artist = raw_input().rstrip("\n")
	while artist == "":
		print "入力されていません。再入力してください"
		sys.stdout.write("アーティスト名 : ")
		artist = raw_input()

	# キーワードを入力
	print "キーワードを入力してください"
	sys.stdout.write("キーワード : ")
	keywords = raw_input().rstrip("\n")
	while keywords == "":
		print "入力されていません。再入力してください"
		sys.stdout.write("キーワード : ")
		artist = raw_input()

	# ディレクトリ作成
	if not os.path.exists(dl_path):
                os.makedirs(dl_path)

	# 権限を付与する
	os.chmod(dl_path, 0777)

	# Amazonからの画像URLのリスト取得
	urls = get_amazon_image_URLs(aws_key, aws_secret, associate_id, searchindex, artist, keywords)

	# 画像をダウンロードする
	download_all_images(urls, dl_path)

	# メッセージの出力
	print "Success! : ダウンロードが完了しました"



スクリプト利用時のスクリーンショットは以下のようになります。


f:id:incodethx3932:20140110232949p:plain

f:id:incodethx3932:20140110232950p:plain






参考にしたWebページは以下です。


Amazonアソシエイトアカウント作成など

Access Key IDとSecret Access Keyの取得 - Amazon Web サービス



Amazon API関連

商品カテゴリーの指定(SearchIndex) - 商品検索(ItemSearch) - Amazon Web サービス

PythonでAmazon Product Advertising APIを使う - 人工知能に関する断創録

PythonでAmazonのAPIを使う - 憧れ駆動開発



Python関連

重複なしリストの作り方(いわゆるuniq) - 図書館断想

つまみがなければ鼻でもつまむ:python defaultencodingがevilな感じ - livedoor Blog(ブログ)

Python で 末尾の改行を削除する : 僕と僕のサル以外、みんな何かを隠してる