【Python】自分のサイトの検索結果の順位をLINEに日次で通知させるてみる

#やりたいこと
自身のサイトが「あるキーワード」でGoogle検索した際の自分の順位をLINEに通知させたい。

##環境を作成する
今回は、Windows10 homeで構築します。
仮想環境を作成して必要なライブラリをインストールします。
###仮想環境を作成する
自身のパソコンがライブラリでゴチャゴチャならないように専用の仮想環境を作っておきます。
作り方は下記を参考にしてみてください。
[Pythonの仮想環境を作成してみる](https://qiita.com/pytomo/items/50b8ee5ea3a3641e6436)

仮想環境を作成したらアクティベートしておきます。

```:コマンドプロンプト
Scripts\activate
```

###ライブラリのインストール
ウェブスクレイピング用のライブラリとherokuで定期実行するためのライブラリをインストールしておきます。

```:コマンドプロンプト
pip install requests
pip install BeautifulSoup4
pip install apscheduler
```


###LINE連携のためのトークンを発行する
下記にLINEにログインしてアクセストークンを発行します。
![LINE Notify - Google Chrome 2020_06_16 14_02_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/59cbf41f-fb6f-a2e1-adff-12c51a5c6828.png)
通知の際に表示されるトークン名と送信先のトークルームを選択します。
今回は自身に送信するので「1:1でLINE Notifyから通知を受け取る」を選択して発行しました。
発行されたトークンを確実に控えます。（閉じるともう見れません）
![LINE Notify - Google Chrome 2020_06_16 14_06_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/64ba8a09-5c10-7dff-c9a7-68250b2a747b.png)

これで連携は完了です。
![LINE Notify - Google Chrome 2020_06_16 14_10_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/df9702a3-6255-faa3-1d14-1702942e5e84.png)

##プログラム作成
Pythonファイルを作成します。
コマンドプロンプトで作成するので、パスは作成した仮想環境の場所に移動しておいてください。

```:コマンドプロンプト
type nul > main_proc.py
type nul > clock.py
```
herokuへのデプロイ後は定期実行するので、スケジュール情報を記載するclock.pyも作成しておきます。

実際のコーディングは下記のとおりです。
本投稿はLINE通知の内容なので、コードの説明は省きます。

```python:main_proc.py
import requests
from bs4 import BeautifulSoup as bs
import os

line_notify_token = os.environ['LINE_NOTIFY_TOKEN']

def main_proc():
    mes = '圏外もしくは未処理'
    targeturl = 'https://sentreseau.com/'
    targetur2 = 'http://sentreseau.com/'

    #リクエストヘッダー　
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}
    list_keyword = 'power platform 福岡'

    url = 'https://www.google.co.jp/search?num=100&q={}'.format(list_keyword)

    #接続
    response = requests.get(url, headers=headers)

    try:
        #HTTPステータスコードをチェック
        response.raise_for_status()
    except:
        mes = '今日は取得できませんでした、残念。'

        
    #取得したHTMLをパース
    soup = bs(response.content, 'html.parser')
        
    #検索結果のタイトルとリンクを取得
    ret_link = soup.select('.r > a')
    mes = url
    for i in range(len(ret_link)):
        #リンクのみを取得し、余計な部分を削除する
        url_txt = ret_link[i].get('href').replace('/url?q=','')
        
        if (targeturl in url_txt) or (targetur2 in url_txt):
            mes = '「{}」で検索した結果、「{}」順位は{}位でした。'.format(list_keyword, targeturl, i + 1)
            break
        
    
    # LINEに通知
    line_notify(mes)

# LINEへの通知関数
def line_notify(message):
    line_notify_api = 'https://notify-api.line.me/api/notify'
    payload = {'message': message}
    headers = {'Authorization': 'Bearer ' + line_notify_token}
    requests.post(line_notify_api, data=payload, headers=headers)


if __name__ == "__main__":
    main_proc()
```

```python:clock.py
import os,main_proc
from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler()

if __name__ == "__main__":
    #毎日07:30に実行
    sched.add_job(main_proc.main_proc, 'cron', hour=7, minute=30)
    sched.start()
    #1分毎に実行
    #sched.add_job(main_proc.main_proc, 'interval', minutes=1)
```

##herokuにデプロイします
herokuの作成は下記サイトが参考になります。
http://www.dcom-web.co.jp/technology/heroku1/

###herokuにログインする
下記コマンドを実行するとログインのブラウザが起動するのでログインします。

```
heroku login
```
![Heroku _ Login - Google Chrome 2020_06_16 15_31_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/771ed989-ff15-3931-a6ae-82609b35c323.png)



###アプリを作成します
```
heroku create アプリ名
```
###buildpackを追加します
herokuでPythonを実行するためにbuildpackを追加します。
※デプロイ時にインストールされる。

```
heroku buildpacks:add heroku/python -a アプリ名
```

###タイムゾーンを変更します。
デフォルトはUTCですので、Asia/tokyoにします。

```
heroku config:add TZ=Asia/Tokyo -a アプリ名
```
###LINEアクセストークンを環境変数に格納します
コードに直接アクセストークンが書いているのは宜しくないので環境変数に格納しておきます。

```
heroku config:set LINE_NOTIFY_TOKEN=アクセストークン -a アプリ名
```

ちゃんとセットされているか下記コマンドで確認してみます。

```
heroku config -a アプリ名
```
###herokuで動かすためのファイルを作成します

- requirements.txt<br/>
サードパーティのライブラリを記載<br/>
下記を実行すれば作成されます。
全て出力されるので、もしかするとherokuのリモートリポジトリにプッシュする際にエラーになるかもしれません。
その場合は、エラーになった部分を削除するなどして対応してください。

```:コマンドプロンプト
pip freeze > requirements.txt
```
- runtime.txt<br/>
Pythonのバージョンを記載<br/>
「python -Version」で確認できます。
（ex）python-3.7.4 
- Procfile<br/>
herokuでWebアプリを動かす指示書のようなものです。
下記のように書きます。
「clock: python clock.py 」

###herokuにデプロイします
（初回のみ）gitの初期ファイルを作成します。
作業フォルダには、「.git」フォルダが作成されます。

```
git init
```
（初回のみ）リモートリポジトリを作成します。

```
heroku git:remote -a アプリ名
```
変更内容をインデックスに追加します。

```
git add .
```
※更新する場合はファイル名を指定します。

```
git add ファイル名
```

コミットします。

```
git commit -m "コメントあれば書く"
```
herokuにでデプロイします。

```
git push heroku master
```

デプロイ後に動作確認してみます。

```:コマンドプロンプト
heroku run python clock.py
```
ちゃんと動作しています。
どうやら弊社は「power platform 福岡」で検索すると投稿時点では４位みたいですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521911/b1b85da9-2163-3080-62b7-54f70bd134fe.png" width=50%>

###定期実行を開始します
herokuにデプロイ後に動作確認までは出来たので、定期実行用にコーディングしたclock.pyが定期実行するようにclockを開始します。

```:コマンドプロンプト
heroku ps:scale clock=1
```
「Scaling dynos... done, now running clock at 1:Free」となればOKです。

これで完了です、毎朝7:30には順位をLINEに通知してくれます。
めでたし、めでたし。

###追伸
ちなみに、herokuで動作中のclockを停止するには下記を実行します。

```:コマンドプロンプト
heroku ps:scale clock=0
```