Pythonで楽天市場の情報を取得して、画像付きで表示する
(Python 2.7.13, iTerm2 Build 3.1.3)
成果物
以下のようにランキングを取得し、画像付きで表示してくれるプログラム
商品情報を取得するAPIは、やはりAmazonの "Product Advertising API" が有名だが、
これは非常に使いづらい上に、ブログの審査が非常に厳しい……
Rakuten Web Service が提供するAPIはとっても簡単に使えるので、そちらを利用する
規模ではAmazonに劣るかもしれないが、ランキングなどの情報は大差ないだろう
アプリIDの発行
- アプリID発行から行う
- アプリ名は適当でオッケー
- ブログで紹介したいときはブログのURLでも貼っておけば良いと思う
- アプリ情報の確認からちゃんと出来てるか確認する
PythonでジャンルIDを取得する
各APIの使い方は、紹介ページに詳しく書いてあるので問題ないはず
例えばランキングを取得したいときは
https://app.rakuten.co.jp/services/api/IchibaItem/Ranking/20170628?[parameter]=[value]…
にリクエストを送れば良い
URLに含まれる日付はAPIのバージョンを表す
今回は requests と BeautifulSoup を使う
Requests の使い方 (Python Library) - Qiita
PythonとBeautiful Soupでスクレイピング - Qiita
指定したジャンルのランキングを取得するためには、ジャンルIDなるものが必要なので、
まずはジャンルIDを取得するAPIを使ってみる
# coding:utf-8 import requests from bs4 import BeautifulSoup URL = "https://app.rakuten.co.jp/services/api/IchibaGenre/Search/20140222" APPLICATION_ID = [APPLICATION ID] GENRE_ID = input() payload = { "applicationId": APPLICATION_ID, "genreId": GENRE_ID, "format": "xml", # 出力形式 "genrePath": 0, # 0:出力結果に祖先ジャンルを含めない 1:含める } response = requests.get(URL, params = payload).text soup = BeautifulSoup(response, "lxml") # genreId, 名前, 階層の深さ のリストを作る id_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("genreid")) name_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("genrename")) level_lis = map(lambda x: int(x.text), soup.findAll("genrelevel")) # 現在の階層を調べる id_index = id_lis.index(str(genre_id)) current_level = level_lis[id_index] # 現在の階層より下の階層にある[ID, 名前]のリストを作る ans = [[i,j] for (i,j,k) in zip(id_lis, name_lis, level_lis) if k > current_level]
入力した番号の階層と、その一つ下の階層にあるIDを返してくれる
一番上のジャンルを表示するときは"0"を指定する
入力した番号の階層が表示されるのは煩わしいので、現在の階層より下のものだけを抽出している
他に取得したい情報があるときは payload = {} 部分に追記すれば良い
terminal上に画像を表示する
せっかくなのでランキング情報は画像付きで取得したい
Mac OS で使える iTerm2 は、アップデートにより画像も表示させられるようになった
【iTerm2】ターミナル上で画像を表示する方法 - Qiita
% imgcat [file name]
だけで画像を表示できる
プログラムから画像を表示するには、以下のようにすれば良い
import commands print commands.getoutput("imgcat [file_name]")
ランキングを取得する
ランキング取得APIでは、画像のURIも取得できる
requests で画像をダウンロードし、imgcatで表示させてみよう
その他の処理はジャンルID取得とほぼ同じ
# coding: utf-8 import requests import commands from bs4 import BeautifulSoup from StringIO import StringIO from PIL import Image URL = "https://app.rakuten.co.jp/services/api/IchibaItem/Ranking/20170628" APPLICATION_ID = [APPLICATION ID] GENRE_ID = [GENRE ID] payload = { "applicationId": APPLICATION_ID, "genreId": GENRE_ID, "format": "xml" } response = requests.get(URL, params = payload).text soup = BeautifulSoup(response, "lxml") # 各パラメータのリストを作ってみる rank_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("rank")) name_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("itemname")) price_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("itemprice")) url_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("itemurl")) im_flag_lis = map(lambda x: int(x.text), soup.findAll("imageflag")) # 1:画像あり, 0:画像なし im_url_lis = map(lambda x: x.text.encode("utf-8"), soup.findAll("mediumimageurls")) # 結果出力 for i in range(10): # 表示したいランキング数 print "%2s位 %s" % (rank_lis[i], name_lis[i]) print "価格 : %s円" % price_lis[i] if im_flag_lis[i] == 1: # 画像が存在するならダウンロードして表示する for im_url in im_url_lis[i].split("\n")[1:-1]: try: im_response = requests.get(im_url, allow_redirects = False, timeout = 1) Image.open(StringIO(im_response.content)).save("image.jpg") print commands.getoutput("imgcat image.jpg") break except: print "unavailable"
このままではそんなに利用価値はないと思う笑
定期的におすすめ本を紹介してくれる Slack Bot などが捗りそう