Re:ゼロからFlaskで始めるHeroku生活 〜PhantomJSをHerokuへ〜

# はじめに
初めてPythonのFlaskとHerokuを使ってスクレイピングした情報をjsonで返すAPIを作ったのでその際に行った方法をまとめたいと思います。

herokuで ***HelloWorld***するまでの環境構築などは前編にあたる
[Re:ゼロからFlaskで始めるHeroku生活 〜環境構築とこんにちは世界〜](http://qiita.com/ymgn_ll/items/96cac1dcf388bc7a8e4e)
にて
今回herokuにデプロイするseleniumとBeautifulsoupでスクレイピングするAPIのコードとその解説などは中編にあたる
[Re:ゼロからFlaskで始めるHeroku生活 〜Selenium & PhantomJS & Beautifulsoup〜](http://qiita.com/ymgn_ll/items/4c2964a14ff80ca2fa28)
にて書いているので、合わせてご覧ください。

# 今回やること
#### 勉強になれば車輪の再発明でもいいじゃない
今回はSlideShareを題材として、SeleniumをとPhantomJSを使ったスクレイピングのやり方を書きます。

***1つの記事にまとめた際長くなってしまった為、seleniumで操作やスクレイピングしているプログラムの内容は中編に分けています。***
# Herokuにデプロイする流れ
## 準備
### Herokuに最終的にあげるファイル

+ api.py
+ Procfile
+ requirements.txt
+ runtime.txt
+ .buildpacks

#### requirements.txtを作る
今回もHerokuにデプロイするために現在のファイル状態を上げる必要があります。

```
$ pip freeze > requirements.txt
```
#### runtime.txtを作る
HerokuがPythonを使う時にどのバージョンのランタイムを使うかを指定するファイルを用意します。

```
$ echo "python-3.5.2" >> runtime.txt
```

#### このファイルまで用意したら現段階までのファイルの準備は終了です。
## HerokuにPushと最終設定
ここまできたら、前回したのと同じように
### gitを適用してコミット
```
$ git init
# フォルダにgitを設定する
$ git add api.py Procfile requirements.txt runtime.txt
# 全てをadd
# 後述の.buildpacksは含まない

$ git commit -m "firstcommit"
# コミットする
```

### Heroku側を作りプッシュ
```
$ heroku login
# herokuにログインする　登録したメルアドとパスを入力

$ heroku create slideshare-api
# herokuに対して新しいプロジェクトを作る
# 同じプロジェクト名は使えないのでやる場合は変えてください

$ git push heroku master
# 作ったherokuプロジェクトにプッシュする
```
まだこの段階ではPhantomJSの準備ができていないのでherokuでは動きません。

### HerokuでPhantomJSを使う
Heroku側にアプリを上げた後、PhantomJSとPythonの両方のbuildpackを使えるbuildpack-multiを使う用に設定を変える必要があります。
どのbuildpackを使うのかを```.buildpacks```ファイルに記述し、コマンドで設定を変更した後にherokuにPushします。
３つのコマンド全てをやってください。
#### buildpack-multiをherokuに追加
```
$ heroku config:add BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-multi.git
```
#### buildpack-multiをherokuにセット
```
$ heroku buildpacks:set https://github.com/heroku/heroku-buildpack-multi.git
```
#### PhantomJSのパスをherokuに設定
```
$ heroku config:add LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib:/app/vendor/phantomjs/lib
```
#### .buildpacksを作る

```
https://github.com/heroku/heroku-buildpack-python.git
https://github.com/stomita/heroku-buildpack-phantomjs.git
``` 
ここまでできたら後はherokuにプッシュ！

```
$ git add .buildpacks

$ git commit -m "add buildpacks"

$ git push heroku master
```

参考 : 
今回はこちらに近い方法でやっています。

+ [Herokuで何か(Node.jsとか)とPhantomJSをつかう方法](http://qiita.com/imaimiami/items/27adefc4745e9b0da22e)

こちらのサイトだと別の方法を書いていますが、自分はうまくいきませんでした。

+ [HerokuでRuby on RailsとPhantomJSの両方を使う方法](http://engineer.gahara.me/entry/heroku-ruby-phantomjs)


## 完成
動くか確かめる
![スクリーンショット 2016-10-17 21.44.52.png](https://qiita-image-store.s3.amazonaws.com/0/93180/be8afa9e-bfd7-84b6-850d-8261ad4469c8.png "スクリーンショット 2016-10-17 21.44.52.png")

動いた！！！！
## エラーが出た場合
前の記事に書いたエラーの場合も合わせて見てください。
herokuのconfigなどに書き込むコマンドはherokuにpushしないとまだ設定を書き込めていないとおもってください。
### PhantomJSがHerokuで動かない！チェック項目
① : HerokuのアプリのFrameworkがMultipackになっているか、及びBuildpacksが```https://github.com/heroku/heroku-buildpack-multi.git```になっているか
![スクリーンショット 2016-10-17 23.17.42.png](https://qiita-image-store.s3.amazonaws.com/0/93180/c1a2abed-c837-4729-cff5-7865c4af4399.png "スクリーンショット 2016-10-17 23.17.42.png")

なっていない場合は```buildpack-multiをherokuに追加```及び```buildpack-multiをherokuにセット```の部分がうまくできていないと思われるのでもう一度コマンドを打った後、なんらかのファイルを変更してherokuへpushしなおしてみてください。

② : heroku logsで確認
以前の記事でも書きましたが、エラーが出た場合

```
$ heroku logs
```
で確認してみてください。
```driver = webdriver.PhantomJS()```の部分、もしくはその後最初にそのdriverを使って要素を指定している場所がエラーメッセージに出ていた場合は、プログラムよりheroku側でうまくphantomjsが使えてないと思われます。 **①** と同じ所をチェックしてみたり、```PhantomJSのパスをherokuに設定```の部分をもう一度して打ってみてからherokuにpushしてみてください。

③ : herokuにvendorができてるかチェック
heroku自体の置き場にアクセスしてみましょう。

```
$ heroku run bash
```
でherokuサーバーにsshのようにアクセスすることができます。うまくphantomJSがherokuに入っていれば

```
~ $ ls
api.py	Procfile  requirements.txt  runtime.txt  vendor
```
のように ***vendor***というのが生成されていて、その中にPhantomJSが入っています。
なければうまく行っていないということなので確認してみると良いでしょう。

## あとがき
ローカルではちゃんと動くのに、herokuにPhantomJSを上げる所や、heroku側でうまく動かないことも多く、詰まることがあると思いますが、がんばってみてください！

また、改善点でしたり、間違い等ございましたら、コメント欄などでご指摘していただけたら幸いです。
Twitter:@ymgn_ll