API RESTを使ってフォト蔵の写真をダウンロードしてみた

#はじめに
pythonを使って、フォト蔵の自分のアカウントにログインし、アルバムの中の写真を取ってくることが出来たのでその方法を書きます。
#作るもの
![demo](https://user-images.githubusercontent.com/28686632/88244706-95199600-cccf-11ea-9904-4919ad95823f.gif)
#対象読者
pythonの基礎終わってる人。
フォト蔵の一括ダウンロードがしたい人。
#環境
macbook Air High Sierra 10.13.6
VScode 1.47.1
Python 3.7
#インストールするもの
Python 3.7
requests 2.24.0
opencv-python 4.3.0.36
pillow 7.2.0
filetype 1.0.7
#仮想環境をつくる
Macのターミナルか、パスが通って入れば、VScodeのターミナルを開いて下記コードを1行ずつ実行すると仮想環境ができあがります。

```python:python.py
pip install pipenv 
mkdir photozou_api
cd photozou_api
pipenv install --python=3.7
pipenv shell
```

`pipenv shell`で仮想環境の中に入れます。
#インポートしたモジュール

```python:python.py
import requests
import json
import pprint
import os
import filetype
import time
from io import BytesIO
from PIL import Image
```
最終的には全部で8このモジュールをインポートしました。
#保存するフォルダーをつくる
```python:python.py
path = '/Users/YOUR PC NAME/Downloads/album'
os.makedirs(path, exist_ok=True)
```

私はローカルのダウンロードフォルダに「album」というフォルダをつくるようにコードを書きました。
`os`をインポートして、`makedirs`で指定した場所にフォルダをつくります。
`exist_ok=True`は、すでに同じ名前のフォルダがあったらスルーするようにするコードです。

#フォト蔵APIからアルバム名を取ってくる
フォト蔵APIの中に`photo_album`というAPIメソッドがあります。

```python:python.py
url = 'https://api.photozou.jp/rest/photo_album.json'
r = requests.get(url, auth=(MAIL, PASSWORD), verify=False)
json_data = r.json()
data = json_data['info']['album']
```

ここから`requests.get`を使って、アルバム名を取得してきます。
[フォト蔵API photo_album](http://photozou.jp/basic/api_method_photo_album)

`json`の中を見ると、`info`の中に`album`があり、その中にアルバム名が入っています。
私の場合、アルバムは複数あります。
なので、`data`の中に`album`という情報をすべて入れて、あとでfor文を使ってアルバム名を取ってこようと思います。
#取ってきたアルバム名でフォルダーをつくる
```python:python.py
for i in data:
    # アルバム名のフォルダーを作成
    path = '/Users/YOUR PC NAME/Downloads/album/' + i['name']
    print(i['name'])
    os.makedirs(path, exist_ok=True)
```
`data`の中にある`name`というのがアルバム名にあたります。

先ほどの`path`の中に`i['name']`を足してあげることで、ダウンロードフォルダに作った`album`の中にアルバム名のついたフォルダが作成されます。
`os.makedirs`を使って、指定したところにフォルダをつくるようコードを書きます。

すべてのコードが完成し、実行した時に、途中でエラーになり、止まってもまた続きからダウンロードがはじまるように`exist_ok=True`を書いておきます。
#ちゃんとすべてダウンロードされたか確認
```python:python.py
    # フォルダーの中のファイルの数を数える
    files = os.listdir(path)
    count = len(files)

    # 写真数比較
    print(i['photo_num'], count)
    
    # ファイル数が写真の数と同じかそれ以上なら
    if count >= i['photo_num']:
        continue
```
フォト蔵のアルバムの中の写真の数と実際にダウンロードした枚数が同じかどうか確認するため、上記のコードをfor文の中に追加します。

if文の中は、ダウンロードした写真の数がフォト蔵のアルバムの写真の数より同じかそれ以上だったら、下に続く画像ダウンロードのコードを飛ばしてもいいというコードです。
#フォト蔵APIからアルバムの写真を取ってくる
次はフォト蔵APIの`photo_album_photo`というAPIメソッドをとってきます。
[フォト蔵API photo_album_photo](http://photozou.jp/basic/api_method_photo_album_photo)

この中にアルバムの中の写真の情報が入っています。

```python:python.py
    # アルバムの中の写真を取ってくる
    url = 'https://api.photozou.jp/rest/photo_album_photo.json'
    payload = {'album_id':i['album_id'], 'limit':'1000'}
    r = requests.get(url, params=payload, auth=(MAIL, PASSWORD), verify=False)
    json_data = r.json()
    data = json_data['info']['photo']
```

`photo_album_photo`のAPIメソッドを`url`に入れます。

`photo_album_photo`には、`album_id`と`limit`というパラメータがあります。
`payload`にはそのパラメータを指定しています。
`limit`が1000なのはフォト蔵の連続アクセスの上限が1000だったからです。

画像を保存する前に、保存したとき、後ろに番号があると今何枚目かわかって、わかりやすいので、数字を数えておこうと思います。

```python:python.py
num = 0
```
#アルバムの中の写真を保存する
```python:python.py
    for j in data:
        time.sleep(0.5)
        # アルバムの写真のタイトル名
        print(j['photo_title'])
        # アルバム内の写真URL
        url = j['original_image_url']
        # 写真のイメージデータを取ってくる
        r = requests.get(url, auth=(MAIL, PASSWORD), verify=False)
        # 写真のデータ形式
        kind = filetype.guess(r.content)
        im = Image.open(BytesIO(r.content))
        # 何枚かを足す1して計算している
        num+=1
        # 写真の名前をつけて保存している
        im.save(path + '/' + j['photo_title'] + '_' + str(num) + '.' + kind.extension)
    # exit()
```
1個目のfor文の中に書きます。

最初にtimeで0.5秒待つように書いています。
これは連続で保存するとフォト蔵APIが、連続で保存しないようストップさせるため、その対策です。

`url`の中に`photo_album_photo`の中の写真の情報を引き渡しています。

`requests.get`で写真のイメージデータを取ってきています。

`filetype`では、その写真のファイル形式がなにか識別しています。
これを使って、その写真が`png`なら`.png`として、`jpeg`なら`.jpeg`として保存できるようにしています。

最後に`opencv`を使って画像を保存しています。
中身は、「保存先」　＋　「画像の名前」　＋　「何番目」　＋　「ファイル形式」としています。

最後にある`exit`を有効にすると、アルバム1つ終わると止まるようになってます。
#おわりに
学生の頃から撮りためていた写真を当時、Googleフォトのようなクラウドの保存先がない時代に利用していました。
が、できればその写真たちをGoogleフォトに移行したいなと思い、挑戦してみました。

文系出身でプログラミング初心者なので間違ったことを書いている部分もあるかと思いますが、大目に見ていただけると恐縮です。

今、アルゴリズムを教えていただいている師匠の力もたくさん借りました。

この記事が私のようにフォト蔵一括ダウンロードしたいのにできないで困っている人の助けになったら嬉しいです。

それと初学者あるあるですが、とりあえず動くものがほしい方もいるかもと下にgithubリンク貼ります。
クローンして必要なモジュールをインポートしたらできるはず...!
[【github】Photozou_all_download_by_APIREST](https://github.com/elain-b/Photozou_all_download_by_APIREST)
#参考サイト一覧
[Python, Requestsの使い方](https://note.nkmk.me/python-requests-usage/)
[[Python] requestsモジュールを使って楽々HTTP(s)通信を行う](https://www.yoheim.net/blog.php?q=20170802)
[Pythonでディレクトリ（フォルダ）を作成するmkdir, makedirs](https://note.nkmk.me/python-os-mkdir-makedirs/)
[Pythonでバイナリ解析する方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/36095#2)
[Python, OpenCVで画像ファイルの読み込み、保存（imread, imwrite）](https://note.nkmk.me/python-opencv-imread-imwrite/)
[PythonでWeb上の画像などのファイルをダウンロード（個別・一括）](https://note.nkmk.me/python-download-web-images/)
[PythonでバイナリをあつかうためのTips](https://qiita.com/pashango2/items/5075cb2d9248c7d3b5d4)
[Pythonの画像処理ライブラリPillow(PIL)の使い方](https://note.nkmk.me/python-pillow-basic/)
[Python3 + Bottle + Pillow でレスポンスとして画像を返す](http://felis-silvestris-catus.hatenablog.com/entry/2015/11/11/212823)
↑神..!ありがとう。この記事なかったら保存できなかった...
[pipenvを使う。pyenv+venvもいいけど、いまどきな'pipenv' で環境構築に使って使い勝手を調べてみた.](https://takuya-1st.hatenablog.jp/entry/2019/04/14/190547)
[【Python】カレントディレクトリのファイル数をカウントする](https://qrunch.net/@1ntegrale9/entries/QTasG4UxdtelIA8S)