scrapyでmysql入れたデータをlogstashを用いてElasticsearchと同期
まずは必要なものをインストール
使用したものはこんな感じです.
- pyenv
- python3.6.2
- MySQL
- mysqlclient
- scrapy
- Elasticsearch
- Kibana
- logstash
pyenvを使ってscrapyを使用するための環境を作成するのは過去の記事でやりました.
http://dmchrt.hatenablog.com/entry/2017/09/08/python導入&scrapy環境構築
今回は実際にscrapyを使用してgunosyニュースを取得し,最終的にはElasticsearchにデータを突っ込んだ手順を追っていきたいと思います.
Scrapyを使用してクローリングし,MySQLにデータを入れるまで
まずはMySQLと,pythonでMySQLを操作するために必要なmysqlclientをダウンロードします.
$ brew update $ brew install mysql $ brew info mysql
mysqlclientをインストールするpyenvの環境のディレクトリで下記を実行.
$ pip install mysqlclient
とりあえずこれでMySQLにデータを入れるのに必要なものは揃いました.
pythonを使ってプログラムを書いていきます.
pyenvで開発環境を整えたディレクトリでプロジェクトを作成し,treeコマンドで確認します.
$ scrapy startproject gunosy $ cd gunosy $ scrapy genspider gunosy_spider gunosy.com $ tree . ├── gunosy │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ └── settings.cpython-36.pyc │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.cpython-36.pyc │ └── gunosy_spider.py └── scrapy.cfg
まずはitems.pyとsettings.pyを編集します.
特にsettings.pyでダウンロード間隔を設定しないとサイトに迷惑がかかってしまうので必ずしましょう.
#items.py import scrapy class GunosyItem(scrapy.Item): url = scrapy.Field() タイトル = scrapy.Field() 元記事サイト名 = scrapy.Field() 更新日 = scrapy.Field() 取得日時 = scrapy.Field()
#settigs.py DOWNLOAD_DELAY = 3 #コメント化されてるのでコメントを外す.
ここまでできたら次は実際にspiderのコードを書いていきます.書き方は様々でしょうが,私は下記を参考にこのように書きました.
Python3でMySQLを使う – 基本操作からエラー処理までサンプルコード付 | Crane & to.
#gunosy_spider.py #必要なものをインポート import scrapy from gunosy.items import GunosyItem import datetime import MySQLdb import atexit #終了時に接続を切るのに使用 #データベース接続とカーソル作成. connection = MySQLdb.connect( host='localhost', user='root', passwd='*****', db='sample_db', charset='utf8') cursor = connection.cursor() cursor.execute("DROP TABLE IF EXISTS `gunosy_data`") class GunosySpiderSpider(scrapy.Spider): name = 'gunosy_spider' allowed_domains = ['gunosy.com'] start_urls = ['https://gunosy.com/categories/14'] def parse(self, response): #詳細ページをパルス for href in response.xpath('//div[@class="list_title"]/a/@href'): yield response.follow(href, self.parseItem) #次のページをパルス for href in response.xpath('//div[@class="pager-link-option"]/a/@href'): yield response.follow(href, self.parse) #詳細ページの処理 def parseItem(self, response): item = GunosyItem() item['url'] = response.url item['タイトル'] = response.xpath('//h1[@class="article_header_title"]/text()').extract_first() item['元記事サイト名'] = response.xpath('//ul[@class="article_header_lead"]/li[@class="article_header_lead_by"]/text()').extract_first() item['更新日'] = response.xpath('//ul[@class="article_header_lead"]/li[@class="article_header_lead_date"]/@content').extract_first() item['取得日時'] = datetime.datetime.utcnow() + datetime.timedelta(hours=9) # エラー処理 try: # CREATE cursor.execute("""CREATE TABLE IF NOT EXISTS `gunosy_data` ( `id` int(11) NOT NULL auto_increment primary key, `url` text not null, `タイトル` text NOT NULL, `元記事サイト名` text, `更新日` text, `取得日時` datetime ) """) # INSERT cursor.execute( "INSERT INTO gunosy_data (url, タイトル, 元記事サイト名, 更新日,取得日時)" "VALUES (%s, %s, %s, %s, %s)", (item['url'], item['タイトル'], item['元記事サイト名'], item['更新日'], item['取得日時'])) except MySQLdb.Error as e: print('MySQLdb.Error: ', e) yield item #プログラム終了時に呼び出され,接続を閉じるメソッド. def endMethod(): print ('\n\n\n\nFINISHED\n\n\n') # 保存を実行(忘れると保存されないので注意) connection.commit() # 接続を閉じる connection.close() atexit.register(endMethod)
これをmysqlで確認してみるとちゃんとデータが入っていました.
MySQLのデータをElasticsearchに突っ込む
次はMySQLに入れたデータをlogstashを用いてElasticsearchに入れていきます.
まずは必要なElastichsearch,Kibana,logstashをインストールします.
Download Elasticsearch Free • Get Started Now | Elastic
Download Kibana Free • Get Started Now | Elastic
Download Logstash Free • Get Started Now | Elastic
インストールしたら,logstashの設定ファイルを書きます.書いたのですが,正直詳しいことはまだ理解していません.; ;
とりあえずこのように書いて,ファイル名はgunosy.confにしてlogstashディレクトリに置きます.
input { jdbc { jdbc_driver_library => "mysql-connector-java-5.1.44/mysql-connector-java-5.1.44-bin.jar" jdbc_driver_class => "com.mysql.jdbc.Driver" jdbc_connection_string => "jdbc:mysql://localhost:3306/sample_db" jdbc_user => "root" jdbc_password => "dnt2626h8" statement => "SELECT * FROM gunosy_data" type => "gunosy" use_column_value => true tracking_column => "id" tracking_column_type => "numeric" clean_run => true } } filter { } output { elasticsearch { index => "gunosy_index" hosts => ["localhost:9200"] document_id => "%{id}" document_type => "gunosy_type" } stdout {codec => rubydebug {metadata => true }} }
そしてそれぞれ起動します.
elasricsearchディレクトリで下記を実行
$ bin/elasticsearch
kibanaディレクトリで下記を実行
$ bin/kibana
logstashディレクトリで下記を実行
$ bin/logstash -f gunosy.conf
データが入っているか確認.
kibanaでdev toolsで確認してみます.
ブラウザでhttp://localhost:5601/にアクセスしてDev Toolsで下記を実行
GET gunosy_index/_search { "query": {"match_all": {} }, "size": 30, "sort": [ { "id": { "order": "asc" } } ] }
これでElasticsearchにデータが入ったこともわかると思います.
elasticsearch-headを使って確認するのも便利かもしれません.
これからやること
logstashの設定がいまいちよくわかってないので,スケジューリングとか,そこらへんを色々やってみたいと思います.
python導入&scrapy環境構築
pythonの導入,scrapyを使用するための環境構築などをまとめます.
まず,このサイトを参考にpythonを入れました.
qiita.com
最初に,Pythonのバージョン管理や,仮想環境を構築できるpyenvを入れました.
仮想環境を使えると,この環境では◯◯のパッケージが使えて,こっちでは△△が使えて,みたいな住み分けができて便利みたいです.システムに直接ダウンロードしちゃうと干渉が起きたりした時に対処が大変なんですかね.
このサイトにも,scrapyを使う場合,仮想環境を使うことが推奨されていました.
インストールガイド — Scrapy 1.2.2 ドキュメント
後ほど詳述しますが,このサイトではvirtualenvを用いていますが,私はpyenv-virtualenvを使用しました.(名前がややこしいですがこの二つは別物みたいです)
それでは,実際にやった手順を追っていきたいと思います.
まず,pyenvをインストール.
$ brew install pyenv
私の環境ではzshを使っているので,
.zshrcに下記を追加.
export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)"
追記したのちにリフレッシュ
$ source .zshrc
インストール可能なpythonの一覧をコマンドで確認.
$ pyenv install -l
実行した時に最新のバージョン(3.6.2)をインストールしました.
$ pyenv install 3.6.2
インストールされたバージョンを確認
$ pyenv versions * system (set by /Users/****/.pyenv/version) 3.6.2
アクティブにするバージョンを選択.
$ pyenv global 3.6.2
確認してみると,
$ pyenv versions system * 3.6.2 (set by /Users/****/.pyenv/version)
pythonを正しくインストールできたか確認.
$ which python /Users/****/.pyenv/shims/python
ここまでで,とりあえずpythonのインストールをすることができました.次は仮想環境を構築するためのpyenv-virtualenvを入れていきたいと思います.
このサイトを参考にさせていただきました.
qiita.com
pyenv-virtualenvのインストール
$ brew install pyenv-virtualenv
インストール終了後,.zshrcを書き換え.(先ほど追記した部分を書き換えました.)
## Set path for pyenv export PYENV_ROOT="${HOME}/.pyenv" if [ -d "${PYENV_ROOT}" ]; then export PATH=${PYENV_ROOT}/bin:$PATH eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" fi
リフレッシュ.
$ source .zshrc
ここからscrapyをインストールするための仮想環境を作っていきます.
まず,適当にフォルダを作成し移動.
$ mkdir ~/Desktop/pyenv_sc $ cd ~/Desktop/pyenv_sc
pythonのバージョンを確認.
$ pyenv versions system * 3.6.2 (set by /Users/****/.pyenv/version)
先ほど,globalでアクティブにしたので,3.6.2が設定されています.
仮想環境を構築し,確認.
$ pyenv virtualenv 3.6.2 sc ..... $ pyenv versions system * 3.6.2 (set by /Users/****/.pyenv/version) 3.6.2/envs/sc sc
仮想環境に切り替え,確認.
$ pyenv local sc (sc)$ pyenv versions system 3.6.2 3.6.2/envs/sc * sc (set by /Users/****/Desktop/pyenv_sc/.python-version)
これで,このディレクトリに映るたびに自動でsc環境が使用されます.この状態でパッケージをインストールすると,この仮想環境にインストールされ,他の環境に影響を与えません.
環境を削除する場合は
$ pyenv uninstall sc pyenv-virtualenv: remove /Users/****/.pyenv/versions/3.6.2/envs/sc? (yを入力)
削除されたか確認.
$ pyenv versions pyenv: version `sc' is not installed (set by /Users/****/Desktop/pyenv_sc/.python-version) system 3.6.2
これで仮想環境構築の流れを追うことができました.
以上をまとめると,下記のようになります.
## pyenvのインストール $ brew install pyenv ## pyenv-virtualenvのインストール $ brew install pyenv-virtualenv ## .zshrcに追記 ## Set path for pyenv export PYENV_ROOT="${HOME}/.pyenv" if [ -d "${PYENV_ROOT}" ]; then export PATH=${PYENV_ROOT}/bin:$PATH eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" fi ##リフレッシュ $ source .zshrc ##pythonのバージョンを確認し,インストール,アクティブ化. $ pyenv install -l $ pyenv install 3.6.2 $ pyenv global 3.6.2 $ pyenv versions ##パッケージをインストールするための仮想環境を構築するためフォルダを作成し,移動. $ mkdir ~/Desktop/pyenv_sc $ cd ~/Desktop/pyenv_sc ##仮想環境を構築し,切り替え. $ pyenv virtualenv 3.6.2 sc $ pyenv local sc
以上です.
■
cakePHPの環境構築から開発開始までまとめ
sudo apt-get update sudo apt-get install libmcrypt-dev sudo apt-get install php-mcrypt sudo apt-get install php-curl curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew chmod +x phpbrew sudo mv phpbrew /usr/local/bin/ phpbrew init [[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc phpbrew lookup-prefix ubuntu phpbrew install 7.0.11 +default +mysql +pdo +fpm +opcache +intl phpbrew switch php-7.0.11 phpbrew use php-7.0.11
下記を実行してphp-7.0.11が入っていることを確認.
php -v
そのあと
php -i|grep intl
を実行しintl拡張が入っていることを確認.
下記を実行しapacheがphp7.0を使うように設定(?)
sudo add-apt-repository ppa:ondrej/php -y sudo apt-get update -y sudo apt-get install php7.0-curl php7.0-cli php7.0-dev php7.0-gd php7.0-intl php7.0-mcrypt php7.0-json php7.0-mysql php7.0-opcache php7.0-bcmath php7.0-mbstring php7.0-soap php7.0-xml php7.0-zip -y sudo mv /etc/apache2/envvars /etc/apache2/envvars.bak sudo apt-get remove libapache2-mod-php5 -y sudo apt-get install libapache2-mod-php7.0 -y sudo cp /etc/apache2/envvars.bak /etc/apache2/envvars
phpmyadminをインストール
phpmyadmin-ctl install
「phpMyAdminのログインとセットアップ」
ログイン:
Cloud9のIDと同じIDでログインする。パスワードは最初は設定されていないので空欄。
設定:
「一般設定」の「サーバ接続の照合順序」: utf8_general_ci
外観の設定:
「言語」を「日本語」
ユーザパスワードの設定:
「ユーザ」タブを開いて該当ユーザIDの「特権を編集」リンクをクリック。
下の方へスクロールすると、「パスワードを変更する」とあるのでそこでパスワードを入れ、
右下に見える「実行」ボタンをクリックする。
composerのインストール
curl -s https://getcomposer.org/installer | php
cakePHPのインストール
php composer.phar create-project --prefer-dist cakephp/app 作成したいプロジェクトの名前
必要なライブラリ類をプロジェクトにインストール
cd 作成したプロジェクトの名前 composer install
ブラウザから確認
https://ワークスペース名−ユーザID.c9users.io/プロジェクト名
configフォルダのapp.phpを開き、データベース設定を記載する
プロジェクトフォルダ\configにあるapp.phpファイルを開き、「Datasources」という文字列を検索。
(私の場合217行目にありましたが、その時点のバージョンにより数行の変動があると思います。)
そこから12行程度下までスクロールさせると 'username' => という記載が見つかるのでそこから下を修正。
'username' => 自分のDBユーザ名
'password' => パスワード
'database' => データベース名
'timezone' => '+09:00',
bootstrup.phpも修正する
同じフォルダにあるbootstrup.phpを開き、「timezone」と記載された行を文字列検索する。
date_default_timezone_set('UTC');
date_default_timezone_set('Asia/Tokyo');
cloud9上でのcakePHP3.4の環境構築
どうもダンテです。
今回はブログを始めようと思うきっかけになった
「icloud 9上でのCakePHP3.4の環境構築」
について色々詰まってしまったのでまとめておきたいと思います。
まず、CakePHP3をしようとしたのは新しく始めたバイトで必要になったからです。
そこでドットインストールのCakePHP3入門の通りにしようとしたのですが、
こちらではローカル開発環境を使っていて、cloud9は使ってませんでした。
そこで他のサイトを検索して、下記のサイトを参考にさせていただきました。
(ブログの作法とかよくわかってないんですけど、URLはっつけちゃっていいんですかね。)
Cloud9でCakePHP3【その1】 | トライスターソリューションズ
Cloud9でCakePHP3【その2】 | トライスターソリューションズ
でも、今最新のCakePHPは多分3.4なんで、このサイトの通りではダメでした。
まず、
intl拡張が入ってなかったので、下記のサイトを参考にphp7.0.11とかそこらへん周辺を入れました。
コードは下記の通りにしました。
sudo apt-get update sudo apt-get install libmcrypt-dev sudo apt-get install php-mcrypt sudo apt-get install php-curl curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew chmod +x phpbrew sudo mv phpbrew /usr/local/bin/ phpbrew init [[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc phpbrew lookup-prefix ubuntu phpbrew install 7.0.11 +default +mysql +pdo +fpm +opcache +intl phpbrew switch php-7.0.11 phpbrew use php-7.0.11 php -v
そのあと
php -i|grep intl
をすれば、無事intlが入ってました。
そして【その2】のCakePHPのインストールをしてブラウザから確認をしようとしたのですが、、
これがうまくいきませんでした。
アクセスしようとすると、
Parse error: syntax error, unexpected '.', expecting '&' or variable(T_VARIABLE) in ~~functions.app
と出てきました。
理由はよくわからないんですけど(ちゃんと勉強しないとですね)
エラーの通り,$argsの前の ... を消してみたらエラーは消えました。
これでうまく行けばよかったのですが、
今度は違うエラーが出ました。
これやっちゃダメでした。
CakePHP7が認識されていなかったってわかった時に若干大丈夫なのかな
って思ってたんですけどやっぱダメでしたね。
MVCを作ってブラウザからアクセスしようとしたらエラー吐かれました。
消した...を元に戻しました。
(全部戻せたのかわからないんだけど大丈夫なのかな。。)
細かいエラーメッセージは忘れましたが、
bootstrap.phpの
version_compare(PHP_VERSION, '5.6.0') < 0
がエラーを吐いてました。
phpが5.5.9だよ
って内容ですね。
しかし、上でやったようにphp 7.0.11は入れたし、
php -v
を実行してもちゃんとphp 7.0.11になってたんですね。
ここで詰まって、ダウンロードの仕方とかコマンドの設定がおかしかったのかな、、、
と思い、色々調べたり試行錯誤しました。
様々なサイトをみても「これだ!」というのは見つけられませんでした。
そこで試しに適当なphpファイルを作って
<?php echo PHP_VERSION; ?>
をしてみるとやっぱりphpは5.9.9。
これはちゃんとphp 7を認識してくれていないのかなと思い、たどり着いたのが下のサイト
How to upgrade a PHP workspace to version 7? - Cloud9 Support - Cloud9 Community
英語のサイトですね。大学入ってから何もしてないので読むのが辛いですね。
ここのanswer通りに
sudo add-apt-repository ppa:ondrej/php -y sudo apt-get update -y sudo apt-get install php7.0-curl php7.0-cli php7.0-dev php7.0-gd php7.0-intl php7.0-mcrypt php7.0-json php7.0-mysql php7.0-opcache php7.0-bcmath php7.0-mbstring php7.0-soap php7.0-xml php7.0-zip -y sudo mv /etc/apache2/envvars /etc/apache2/envvars.bak sudo apt-get remove libapache2-mod-php5 -y sudo apt-get install libapache2-mod-php7.0 -y sudo cp /etc/apache2/envvars.bak /etc/apache2/envvars
を実行して、もう一度ブラウザからアクセスしてみると、、
今度はうまくいきました。
どうやら、installするだけじゃなく、apacheに指定してあげないとダメみたいですね。
エラーに書いてる事を素直に受け止めて、php7がちゃんと指定されていないことに気づけば一瞬で解決できたことですね。。。
エラーはちゃんと対処しないとダメですね。
プログラミングは気づかなくて沼にハマると本当に抜け出せなくて辛いですね( ;∀;)
もっと頑張ろう。。