楽天商品検索APIを使って商品情報をcsv出力[Python]

## はじめに
楽天市場のAPIを活用し、キーワードに当てはまる商品情報をcsvに出力してみました。

活用したのはこちらの「楽天商品検索API」というものです。
[楽天ウェブサービス: 楽天商品検索API(version:2017-07-06) \| API一覧](https://webservice.rakuten.co.jp/api/ichibaitemsearch/)

今回の情報収集の目的としては、農産物を販売するための価格調査のために行いました。取得した情報をもとに、さらに分析して意思決定するところまでを想定しています。
（今回は情報取得するところまで行います）。

色々な直販サイトはありますが、楽天市場は馴染みがあり商品数も多く、APIも提供されているので取得しやすいなと考えたため、楽天市場を選びました。

### 開発環境と使用するライブラリ
開発環境としてJupyter Notebookを利用しました。
大掛かりなツールや定期的に実行したいツール作成時にはまた別のテキストエディタで作っていく必要があるかもしれませんが、ちょっとした単発のツールを作る際には、Jupyter Notebookなら少しずつ試しながらスクリプトが書けるし、即座に実行できるのでとても便利です。

使用するライブラリは`request`と`pandas`。
APIを叩くために`request`を使い、取得したデータ操作とcsv出力のために`pandas`を利用しました。

## 楽天APIを扱う準備
APIを活用するためには、スクリプトを書き始める前にまずは楽天の開発者向けページからアプリを作成してIDを取得しなければいけません。

こちらのRakuten Developersのサイト
[楽天ウェブサービス: API一覧](https://webservice.rakuten.co.jp/document/#ichibaApi)

右上の「+アプリID発行」からアプリを作成しておきます。ここで取得したアプリIDを自分のスクリプトで実行する際に使うことで、楽天市場の情報にアクセスでき流ようになります。

楽天市場だけでなく、楽天の他のサービス（楽天トラベルや楽天レシピなど）のAPIもあるのが良いですね。機会があれば使ってみたいです。


## 商品情報を取得するスクリプト
### (1)キーワードを入れて商品情報を取得してみる
今回は「メークイン」というじゃがいもの品種名をキーワードに含む商品情報を取得することにします。

まずは必要なライブラリのインポート。

```python
import requests
import numpy as np
import pandas as pd
```

あとで使いたくなったので`NumPy`も入れておきます。使わなくてもさほど問題はないです。
次にAPIを叩いて情報を取得するスクリプト。

```python
REQUEST_URL = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706"
APP_ID="<ここに楽天のサイトで取得したアプリIDを入れる>"

serch_keyword = 'メークイン'

serch_params = {
    "format" : "json",
    "keyword" : serch_keyword,
    "applicationId" : [APP_ID],
    "availability" : 0,
    "hits" : 30,
    "page" : 1,
    "sort" : "-updateTimestamp"
}

response = requests.get(REQUEST_URL, serch_params)
result = response.json()
```

これで、`result['Items']`とすれば、情報がdict型のlistの形で取得できます。今回は30商品が取得できています（`serch_params`の`"hits":30`で指定している数値です。これが一度に取得できる最大値）

さらに例えば`result['Items'][2]['Item']`とすることで、取得した中から2番目の商品がdict型で取得できます。
　
 　
スクリプトをざっと見ていくと、

`REQUEST_URL`には[楽天ウェブサービス: 楽天商品検索API(version:2017-07-06) \| API一覧](https://webservice.rakuten.co.jp/api/ichibaitemsearch/)に載っているリクエストURLを指定、
`APP_ID`には先ほど楽天の開発者向けページから取得したアプリIDを入れておきます。

`serch_keyword`で検索したい文字列を指定することで、そのキーワードにマッチする商品が検索されます。
ここをPythonの`input()`関数でユーザー入力を受け付けても使い勝手が良さそうですね。

`serch_params`にはリクエストを送る際のパラメータをdict型で書いておきます。[楽天ウェブサービス: 楽天商品検索API(version:2017-07-06) \| API一覧](https://webservice.rakuten.co.jp/api/ichibaitemsearch/)の「入力パラメーター」の項に詳細が載っていますね。このパラメーターには`applicationId`（アプリID）は必須でこれには`APP_ID`を指定、また`keyword`,`shopCode`, `itemCode`, `genreId`のいずれかの指定が必須のようです。
今回は検索キーワードで商品情報を取得したいので、`keyword`に先ほどの`serch_keyword`を指定しました。

例えばこの`"page":1`というのは取得ページなので、この数値をfor文でループを回せば複数ページに渡る大量の商品情報を簡単に取得できそうですね。


### (2)必要な商品情報を入れたdict型を作成
さて、先ほどAPIを叩いて取得できたdictには[楽天ウェブサービス: 楽天商品検索API(version:2017-07-06) \| API一覧](https://webservice.rakuten.co.jp/api/ichibaitemsearch/)の「出力パラメーター」の項に載っている項目がdictのkeyとvalueとして入っています。

例えば`result['Items'][2]['Item']['itemName']`という風にkeyを指定すると、商品名が取得できます。

現段階で取得した情報は、このままだと余計な情報も入っていて扱いが不便なので、必要な情報のみが入っているdictを作ることにします。

今回必要とするデータは
「itemName」「itemPrice」「itemCaption」「shopName」「shopUrl」「itemUrl」
とします（後から、送料フラグ「postageFlag」も必要だなと思ったのですが、以下のスクリプトには反映されておりません）。

```python
# for文を回してdictを作る
item_key = ['itemName', 'itemPrice', 'itemCaption', 'shopName', 'shopUrl', 'itemUrl']
item_list = []
for i in range(0, len(result['Items'])):
    tmp_item = {}
    item = result['Items'][i]['Item']
    for key, value in item.items():
        if key in item_key:
            tmp_item[key] = value
    item_list.append(tmp_item.copy())
```

これで、dict型の商品情報の入ったlistが取得できます。

ここで詰まったのが、`item_list.append(tmp_item.copy())`のところで`copy()`メソッドを使う必要があることでした。
このメソッドを使わず`item_list.append(tmp_item)`としてしまったら、１つの商品情報が複数入ったdictができてしまい、首をひねって日を跨ぐことに。

以下の記事に助けられました。

[Pythonのリストにdict型の変数をappendすると変数がポインタ的に振る舞うので… · GitHub](https://gist.github.com/dogrunjp/9748789)

この理屈は理解しておく必要がありそうなので、また別途まとめたいです。

### (3)pandasでデータを整形
dict型のlistを作ることができたら、あとは難しいことはなく`pandas`の基本操作で事足ります。
データフレームを作り、また活用しやすくするために少し整形しておきます。

```python
# データフレームを作成
items_df = pd.DataFrame(item_list)

# 列の順番を入れ替える
items_df = items_df.reindex(columns=['itemName', 'itemPrice', 'itemCaption', 'itemUrl', 'shopName', 'shopUrl'])

# 列名と行番号を変更する:列名は日本語に、行番号は1からの連番にする
items_df.columns = ['商品名', '商品価格', '商品説明文', '商品URL', '店舗名', '店舗URL']
items_df.index = np.arange(1, 31)
```

### (4)csv出力
作成したデータフレームをcsvファイルに出力します。

```python
items_df.to_csv('./rakuten_mayqueen.csv')
```

`df.to_csv()`メソッドの引数には、保存先のパス（ディレクトリとファイル名）を指定します。今回は相対パスで、このスクリプトがあるディレクトリ直下にcsvファイルを作成しました。

さて、出力されたデータをExcelなりSpreadSheetで開いてみましょう。

![スクリーンショット 2020-09-01 20.28.15.png](https://crieit.now.sh/upload_images/c3de87150b8d6a7b5ddc97919a9f2c545f4e48ce423c9.png)

いい感じに取得することができました！

## おわりに

ひとまず楽天市場から商品情報を取得して、csv出力まですることができました。
[次回](https://qiita.com/Massasquash/items/831ace8b4527d90653a8)は少し込み入ったデータ収集と整形をしてみたいと思います。