サーバー上（Ubuntu16.04）で、Webブラウザを自動実行することで、Web上の特定のデータを定点観測する（３）〜Cron自動実行編〜

# 背景
リアルタイムに値の変わるデータがWEB上にありました。その値を定期的にチェックするプログラムを作ることになったわけですが、ページにログインする必要があったりと、スクレイピングのコードを書くのが面倒でした。その対策としてseleniumを使ってWebブラウザを操作し、スクレイピングをすることにしました。その過程を備忘録的にまとめていきます。

なお、手元のPCを使い、Webブラウザをバッチ処理で自動実行しても良かったのですが、、、普段使いの自身のPC上で、勝手にWebブラウザが立ち上げるのは邪魔だったので、レンタルサーバ上（Ubuntu16.04）で勝手に動かすようにします。

より具体的には以下のイメージになります。
（１）python経由でWebブラウザを立ち上げる　→ [Part1](http://qiita.com/gano/items/f46adc5dff055baf3785)で説明
（２）seleniumでWebブラウザを操作し、WEBデータを処理する　→ [Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)で説明
（３）処理したデータをmongoDBに格納する　→ [Part3(本投稿)](http://qiita.com/gano/items/41111c320577779999a4)で説明
（４）（１）〜（３）を実行するpyプログラムをcronで自動実行する　→ [Part3（本投稿）](http://qiita.com/gano/items/41111c320577779999a4)で説明
（５）値に一定の変動があった場合メールで知らせる　→ [おまけ編](http://qiita.com/gano/items/4935eadce7219eb6227d)で説明

[Part1](http://qiita.com/gano/items/f46adc5dff055baf3785)と[Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)でWeb上の特定のデータを自動取得するプログラムはできているので、後はそのプログラムをCRONで自動実行する設定をします。

# 環境
OS        : Ubuntu16.04(さくらVPS）
python    : version 3.5
mongoDB   : version 2.6.10
PhantomJS : version 2.1.1 

# Step１） CRONの設定を行う

```
# cronの動作確認
sudo service cron status

# cronの設定ファイルを編集
crontab -e
```

crontabには以下のように記述

```
*/5 * * * * <path_to_python>/python3 /<path_to_file/test.py >> /<path_to_log>/test.log 2>>&1
```

上記のように[Part1](http://qiita.com/gano/items/f46adc5dff055baf3785),[Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)で作ったpythonプログラムをジョブに指定してあげれば、５分置きにブラウザが勝手に立ち上がり、特定のサイトの特定のデータを取ってきてくれます。

# Step２） 取ってきたデータをDBに保存する準備
ここからはおまけです。初期設定のUbuntuでこの定点観測プログラムを作ったので、ついでなのでDB格納のメモもしておきましょう。

txtファイルへの出力で良い場合は、書くまでもないですが、

```py:ファイル出力
f = open( "test.txt", "a+" )
f.write( data )
f.close
```

で良いでしょう。

私は実際にはMongoDBで格納しています。

## <b>MongoDBのインストール</b>
以下の手順でインストールします。

```
1) 公開鍵の設定
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

2)　mongodb.listの作成
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

3) 実際にインストールする
sudo apt-get update
#sudo apt-get install mongodb-10gen

4) mongod.serviceの作成
sudo vim /lib/systemd/system/mongod.service

　▼mongod.serviceの中身

　[Unit]
　Description=MongoDB Database Service
　Wants=network.target
　After=network.target

　[Service]
　ExecStart=/usr/bin/mongod --config /etc/mongod.conf
　ExecReload=/bin/kill -HUP $MAINPID
　Restart=always
　User=mongodb
　Group=mongodb
　StandardOutput=syslog
　StandardError=syslog

　[Install]
　WantedBy=multi-user.target
```

（参考URL）　http://qiita.com/pelican/items/bb9b5290bb73acedc282

## <b>pymongoのインストール</b>
pythonからMongoDBを操作するpymongoパッケージをインストールする

```
pip3 install pymongo
```

## <b>MongoDBの起動</b>

```
sudo systemctl start mongod
```

# Step３） ブラウザの自動実行により、WEB上のデータを定点観測するプログラム全容
[Part1](http://qiita.com/gano/items/f46adc5dff055baf3785)と[Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)と本投稿を総合して、簡単な定点観測プログラムを書いてみます。

[Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)と同様、実際に私が観測しているデータは公開できないため、今回もQiitaのトップのフィード内にある投稿を自動取得するプログラムを書いてみましょう。

プログラムの中身を整理するとこうなります。
（１）ブラウザPhantomJSを立ち上げる
（２）Qiitaに自動的にログインをしてフィードの上から２０個の投稿名を自動取得します。
（３）（２）で得た投稿名をリストに格納し、MongoDBに出力します。
　
実際のプログラムコードは以下のようになります。

```
import time
import datetime

from selenium import webdriver
from bs4 import BeautifulSoup

URL = "https://qiita.com/"
USERID = "<YOUR_USER_ID>"
PASS = "<YOUR_PASSWORD>"

#PhantomJSの自動起動とQiitaへのアクセス
browser = webdriver.PhantomJS(executable_path='<path/to/phantomjs>')
browser.get(URL)
time.sleep(3)

#ログインページ
browser.find_element_by_id("identity").send_keys(USERID)
browser.find_element_by_id("password").send_keys(PASS)
browser.find_element_by_xpath('//input[@name="commit"]').click()
time.sleep(5)

#ホーム画面の投稿一覧の取得
html = browser.page_source.encode('utf-8')
soup = BeautifulSoup(html, "lxml")
posts_source = soup.select(".item-box-title > h1 > a")

#投稿名のデータ整理
posts = []
for i in (0,len(posts_source)):
　posts[i] = post.text.strip()

#定点観測の時刻を取得
output = {}
output["date"] = str(datetime.date.today())
output["datetime"] = str(datetime.datetime.today().strftime("%H:%M:%S"))
output["content"] = posts

#MongoDBへ格納
mongo = MongoClient('localhost:27017')
db = mongo_client["qiita"]
new_posts = db_connect["new_posts"]
new_posts.insert(output)

#ブラウザを閉じる  
browser.close()
```

こんな感じです。このプログラムをcronで定期実行することで、Qiitaのログイン後のフィードから最新の投稿名を２０件記録します。（投稿用のテストプログラムのため実用性はないかと思います^^;)

このプログラムを応用すれば、GET/POSTの有無に関わらず、様々なWEBページの中のデータを定点観測することができるようになります。