インスタグラムアカウントの運営をPythonで自動化してみた

## お詫び（2020年4月12日現在）
現時点において、インスタグラムのセキュリティに変化があり、本内容は通用しない可能性が高いです。お詫び申し上げます。近日中に記事を削除します。

# はじめに

数日前に

[Pythonによる自動化の結果、ニューヨーク中でタダメシが食えるようになったエンジニアの話](http://developer.cybozu.co.jp/akky/2019/04/free-dish-by-python-automation/)

こちらの記事を読んで衝撃をうけ、思った。

「・・・これやりてぇ・・・」

記事を要約すると「インスタグラムのアカウント運営をPythonで書いたプログラムで完全自動化して、経済的な対価を得よう」みたいなことだ。元記事は英語で下記のリンクから読んでみてほしい。

[How I Eat For Free in NYC Using Python, Automation, Artificial Intelligence, and Instagram](https://medium.com/@chrisbuetti/how-i-eat-for-free-in-nyc-using-python-automation-artificial-intelligence-and-instagram-a5ed8a1e2a10)

記事内で参照されている、自動運営されているというアカウントは

https://www.instagram.com/beautiful.newyorkcity

<img width="949" alt="スクリーンショット 2019-05-19 11.24.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18165/1eb11d22-7f58-70a2-0c1b-e78223a0932a.png">

これで、正直、よくこういうの見るな・・・という印象ではあるが、一見して、自動化されているとは思えない。

<img width="951" alt="スクリーンショット 2019-05-19 11.27.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18165/57f02a53-5702-a09b-d8fe-8a667d400e36.png">
https://www.instagram.com/p/BwiHTjel7IJ/

基本的には、ニューヨークの綺麗な写真が投稿されているが、時々こういう #sponsored とタグのついた投稿があり、これがタダ飯ということなのだろう。

さて、これを、一日プロジェクトでやっていきたいと思う。

# 方針

基本的には、こういうときは、小さな課題に分解して、ひとつずつ潰していくやり方が良いなと思っている。あんまり考えずに、一気にやりたくもなるが、問題が複雑すぎると、一気にやりきれず後で後悔するケースが多い。問題を分解して潰しながらやっていくと、確実に進捗が残るので、好きです。

さて、ざっと課題を整理すると

1. テーマ選定の作成
2. アカウントの作成
3. ロゴの作成
4. インスタグラムへのプログラム経由投稿
5. 画像選定
6. コメントハッシュタグ
7. 定期実行

の7個程度になるかなと思う。

ここで、この記事は、やりながら書いていることを断っておきたい。ぶっちゃけると、すでにロゴ作成までは終わっている。これは、記録として公開したら面白いかな・・・？と思って、ロゴ作成まで追いつこうと思って書いているのが正直なところ。

言語は、Pythonでやっていきたい。

では、インスタグラムアカウントの運営自動化をやっていく！

##1. テーマ選定の作成
正直タダメシ狙うというのは、難しいかなと思っているので、単純に今興味があってインスタ映えしそうなテーマであれば何でも良いと思う。個人的に好きな、ウイスキー、日本酒、ワインの3つが候補にあがったが、あまり深い理由なく、ワインをテーマとすることにした。
名前は「WineMania(@winemania2019)」
https://www.instagram.com/winemania2019/

日本人のワイン好きをテーマにしてみた。ちょっとマーケットが小さすぎるかもしれない。

## 2. アカウントの作成
ここは、ハック要素ゼロなので、普通にインスタグラムのWeb版から作っていきましょう。

https://www.instagram.com/

## 3.　ロゴの作成
最近は、

https://www.launchaco.com/logo

このlaunchaoという無料のロゴジェネレーターがお気に入りです。お気に入りのフォントとアイコンをポチポチするだけで、無限にロゴを提案してくれます。

![icon-above-font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18165/36f7327e-673a-d2aa-d03c-7d7836d25801.png)

できたものがこちら。3分でできました。

## 4.インスタグラムへのプログラム経由投稿
ようやくプログラムを書くところに入ってきました。

### ライブラリ選定

残念ながら公式のAPIを使ってということは、規約上難しいので、うまくハックする必要があります。幸いインスタグラム界では、第三者による非公式APIを利用した、インスタ操作プログラムがたくさんあります。その中から

・Python
・投稿ができる
・簡単に使えそう
・Starがたくさんついている
・メンテナンスがされている
・（あわよくば）ドキュメントが充実している

という点から選んでいきます。

そこで・・・ドン！

instagram_private_api
https://github.com/ping/instagram_private_api

このを使うことにしました。Starも700以上ありますし、最新の更新も数ヶ月以内です。ちょっと物足りないですが、15分ほどググった中ではベターだったので、これを採用して先に進むことにします。

### インストール
インストールしていきます。Pythonやpipなどの環境が入っていることは前提としますね。一応自分は、pythonのバージョンは、anaconda3-4.1.1を使っています。

```
pip install instagram_private_api
```

### Hello world
Hello world的なことをします。下記のIDとパスワードは上で作成したアカウントのものに差し替えてください。

```python
from instagram_private_api import Client, ClientCompatPatch

user_name = '<インスタグラムアカウントのID>'
password = '<パスワード>'

api = Client(user_name, password)
results = api.feed_timeline()
```

で、

```
python bot.py
```

エラーなく、動くかなと思います。

### 投稿のテスト

```python
from instagram_private_api import Client, ClientCompatPatch
from PIL import Image
import io
import urllib.request

user_name = '<インスタグラムアカウントのID>'
password = '<パスワード>'
api = Client(user_name, password)

# 画像のURL
url = "https://user-images.githubusercontent.com/5179467/57978324-23e4b000-7a46-11e9-8b04-4d16e97a702c.jpg"

# 画像データを取得する
img_in = urllib.request.urlopen(url).read()
img_bin = io.BytesIO(img_in)
img = Image.open(img_bin)

# 画像を投稿する
api.post_photo(img_bin.getvalue(), (img.width, img.height))
```

画像は、そのまま使っていただいてもOKです。jpgじゃないと駄目なようです。
すると

<img width="816" alt="スクリーンショット 2019-05-19 16.15.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18165/e875b1a1-2621-c0e0-a9f3-fd7d25bceeb0.png">


投稿されます！
とても簡単ですね。

## 5. 画像選定
ここは、モラル的な問題もあるので、どうかなと思うが、元記事では、当初有名アカウントを選定し、そこから著作権をケアするために、引用でうまくやっていたとのこと。ただ、この記事でそれをやるとウルトラ炎上しそうなので、ぐっとこらえて、フリーの画像サイトUnsplashから利用することにします！

※注意ですが、Unsplashの画像を使って本番で運用する気はありませんので、あしからず！あくまでも、実装のテストに使うだけです。

Unsplash
https://unsplash.com

APIキーを取得しておいてください。
ざっとしたみたいな感じの関数にしました。

```python
from unsplash.api import Api
from unsplash.auth import Auth

def fetch_image_url():
  client_id = "<UnsplashのClientID>"
  client_secret = "<UnsplashのClientSecret>"
  auth = Auth(client_id, client_secret, '', code='')
  api = Api(auth)

  check_count = 0
  
  # 画像の縦横比が一定以下じゃないと（極端な縦長は駄目）いけないので、チェックする
  while True:
    check_count += 1
    # wineの箇所をお好みのキーワードに変更してください
    random_photo = api.photo.random(query='wine') 
    image_url = random_photo[0].urls.raw + "?fit=crop&w=500"
    img_in = urllib.request.urlopen(image_url).read()
    img_bin = io.BytesIO(img_in)
    img = Image.open(img_bin)
    width = img.width
    height = img.height
    ratio = height / width
    if ratio <= 1.2:
      break
    elif check_count >= 10:
      image_url = None
      break
  
  return image_url
```

UnsplashのAPIを使ってランダムに画像のURLを取得する関数です。
query='wine'の箇所を変えると好きなカテゴリーの画像になります。

## 6. コメントハッシュタグ
今回は、3個程度のハッシュタグを選定してつけるだけにします。コメントはもっと凝ったほうがいいのですが、時間がかかりそうなので将来の課題とします。こういうのは細かいところにこだわらずに、一度一気通貫させることが大事だと思います。

ワインがテーマなので、

 `#wine #ワイン #ワイン好き`

あたりでしょうか。

投稿に関しても下記のように関数化しました

```python
from instagram_private_api import Client, ClientCompatPatch
from PIL import Image
import io
import urllib.request

def post_image(image_url, comment=''):
  user_name = '<インスタグラムアカウントのID>'
  password = '<パスワード>'
  api = Client(user_name, password)

  # 画像のURL
  url = image_url

  # 画像データを取得する
  img_in = urllib.request.urlopen(url).read()
  img_bin = io.BytesIO(img_in)
  img = Image.open(img_bin)

  # 画像を投稿する
  aapi.post_photo(img_bin.getvalue(), (img.width, img.height), caption=caption)
```

では、画像の取得から投稿までを行ってみます。

```python
tags = '#wine #ワイン #ワイン好き'
image_url = fetch_image_url()

if image_url == None:
  print('Sorry, good image not found!')
else:
  post_image(image_url, tags)
```

これらを実行すると

<img width="986" alt="スクリーンショット 2019-05-19 16.16.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18165/29dbf05c-9661-f92c-a265-cd1c36813c66.png">

いい感じに投稿することができました。

https://www.instagram.com/p/Bxoqo50FJcA/
ここで確認いただけると思います。

## 7. 定期実行
さて、最後の定期実行ですが・・・お詫びですが、個人的に時間切れになってしまったので、宿題にしたいと思います！

選択肢としては
・自分でサーバーを立ててcronで定期実行する
・AWS Lambdaなどのサーバーレス環境を使って定期実行する
・ローカルで定期的に手動で実行する

などあると思いますが、個人的には、AWS Lambdaなどのサーバーレス環境をうまく使うのが良いかなと思っています。後は定期実行すれば、インスタグラムの自動運用アカウントの管制です。

# まとめ
さて、いかがだったでしょうか。結構さくっと一気通貫（定期実行はできませんでしたが・・・）できたかなと思います。みなさんもぜひやってみてください。