AWSを使って欲しい情報を自動取得する

やりたいことの概要

技術的にはクローリングとかスクレイピングとか呼ばれている。

クローリングはWebを自動で徘徊する技術で、スクレイピングはさらに欲しいものだけ抽出するような感じ。

例えばポータルのほうで技術ニュースリンクをまとめてるのはこの技術を使っている。

方法は色々あるけどAWSで簡単にできそうなものを2つ実装している。

けどいまいちしっくりこないので現状をまとめつつ、どう運用するのが一番いいか考えてみる。

1つ目の方法はEC2にヘッドレスブラウザを入れてJenkinsで管理するやり方。

2つ目の方法はLambdaで起動してCloudWatchで管理するやり方。

どっちもスクレイピング自体はjavascriptを中心にした方法で実現している。

方法1

概要

■EC2+phantomjs+casperjs+Jenkins

EC2インスタンスを立ち上げてその中で好きなようにしようというスタンス。

phantomjsはヘッドレスブラウザでcasperjsはそのユーティリティ。

javascriptで実行できる画面描写のないブラウザを利用して情報を集める。

Jenkinsのジョブで収集スクリプトを起動したり、データを格納したりする。

メリット

インスタンス内でできることは何でもできるので拡張性が高い。

デメリット

インスタンスのメンテナンスが必要。EC2インスタンスは起動時間課金なのですでに運用しているインスタンスに相乗りしたり、必要に応じて起動/停止をしないとお金がかかる。

スクレイピング実行部分のサンプル

ブラウザとして巡回するので広告ページを待ったりしている。

ヘッダをいい感じに設定すれば特に待つ必要はないかもしれない。

方法2

概要

■Lambda+nodejs+cheerio-httpcli+CloudWatch

インスタンスを保持せずサービスとして使おうというスタンス。

cheerio-httpcliはnodejsのスクレイピング用モジュール。

LambdaにZIPを置いてevent sourceでCloudWatch Events – Scheduleを設定する。

メンテ不要でAWSの他サービスが使いやすい利点がある反面、Lambdaの制限がある。

特にマックス300秒の制約を気にしないといけないかも。

起動以外は取得、整形、格納なんかは全部Lambdaの中で行う。

メリット

実行時間のみ課金されるので使わないときのメンテが不要。

AWSの他サービスを使いやすい(IAM ロールの設定などが簡単)。

デメリット

Lambdaの制約内でやる必要があるので拡張性は低め。

スクレイピング実行部分のサンプル

書き方は色々あるけど一番簡単そうなPromise数珠繋ぎで書いている。

cheerio-httpcliに関しては作者さんがかなり丁寧に解説しているので使いやすかった。

まとめと感想

どちらも多少ニッチな知識が必要だけどjavascriptを多少知っていれば難しいとこはないし、ググればすぐに情報が手に入るので実装は簡単だった。

クライアントアプリケーションを途中でかませたりするような場合にはEC2内でやって、AWS内だけで済む処理なら基本Lambdaにするのがいいかなと思う。

今回の組み合わせの他にもEC2でnodejs動かしたり、Lambdaでphamtomjs動かしたりする例も見かけたけど特にそうする理由はなさそう。

kimonoみたいな専用サービスを使うとスクレイピング実施部分はほぼノータイムでできるんだろうけど、利用するサービスが増えると色々と面倒見ないといけなくなりそうなのでしばらくはAWSに依存してみようと思う。

 

新アプリ「マイルーレット」をリリース

数日前にAndroidアプリをリリースしました。

このアプリはサイコロを作っていたときに面の数とか内容を自由に変えたいなーと思ったのがきっかけで作り始めた。

文を表示させるならサイコロよりルーレットかなー、ルーレットっていうとディーラーが回すやつとかスロットで回ってるアレみたいな感じかなーと思ったのでどっちもできるようにした。

技術的に難しいことはしなかったけど、ぐるぐる回す処理は演算しながら再描画するよりも設定変更毎に画像化してまわしたほうが負荷が小さかったかもしれない。

 

このアプリで浮き彫りになったのは絶望的な画像センスのなさ。

アイコンはコレだし

myricon

バナーはコレ

myrbanner

まじめに作ってるんだけどね。

どうやってもイイネってなるものを作れそうになかったので妥協した感じがある。

勉強すれば改善できるものなのか、何を勉強すればいいものなのか。

いずれ差し替えよう。いずれ。。

引越し完了

引っ越しました

会社の寮に入っていたので退職に伴って引越ししました。

今週はほとんど引っ越しに費やしたけどようやくひと段落。

荷解きも大体終わった。

最初は集合寮住まいだったので大ダンボール3箱で上京してそのまま個別寮に入ったけど、今回は大7つ小8つにもなっていた。

ここを出るときには大3つくらいに収まるようにミニマリストを参考にしてみようと思う。

急な引越しでどたばたしたのでタイムスケージュールを残しておく。

1ヶ月前

物件を探す

まず引越し先が見つからないと何もできない。

一ヶ月前くらいには抑えたいが人気物件だったり繁忙期などでもっと直近で契約しなくてはいけない場合がある。

閑散期であれば余裕を持って契約できたり、フリーレントの条件がつきやすいと聞いた(今回は1ヶ月のフリーレントをもらえた)。

引越し屋を探す

安くても評判の悪いところは使わないほうがいい。

一人暮らしなら最安と2番目の違いはほとんどない。

不動産屋とつながっているところだと多少融通が利く。

各種切り替え連絡をする

ガス、電気、水道、郵便など最近はネットでできるようになっている。

粗大ゴミを捨てる

市や区の回収サービスを使うのであれば予約が埋まっているかもしれないので早めに申し込みする必要がある。

自分で持ち込んだり、引越し屋に回収してもらう方法もある。

1週間前

荷造りをはじめる

量によってはもっと前から計画的に片付けたほうがいいが、ダンボール置き場を用意しておく必要がある。

当日

引越し

引越し屋が来る前に忘れ物がないか確認する。

旧物件引渡し

一通り掃除して旧物件を大家さんに引き渡しする。

室内点検や鍵の返却をするけど、大体は自然消耗として扱われるので基本清掃料だけですむはず。

荷下ろし

新居に荷物を下ろす。

複数の引越しを並列してやる引越し業者なら数の確認をきちんとする。

あとダンボールの回収の有無など確認しておく。

ガスの立会い

電気、水は連絡するだけでいいけど、ガスだけは引越し先で立会いが必要な場合が多い。

引越し後

住民票の変更

必要書類を持って転居届けを出す。

(市区町村が変わる場合には転出届と転入届が必要)

免許とか銀行とかもろもろ住所変更

面倒でもちゃんとしておかないと後々面倒なことになる。

 

AWSのDynamoDBをAPIでCRUD操作する

概要

DynamoDBをAPIで使えるようにした。

次にAPIを通じてCRUD操作する方法を記録しておく。

基本的に公式ガイドを参照したけどわかりにくかったので他も色々見ながら試行錯誤した。

検索するといろんな情報(古い書き方、非推奨の書き方や別の言語での書き方)が入り混じっていて結構わかりにくかった。

create レコードを新規作成

payload.TableNameで指定したテーブルにpayload.Item内のJSONを新規登録する。

テーブル作成時にプライマリーキーに設定した属性は必須。

それ以外はJSONであれば自由。

また、プライマリーキーの値がすでにあるものであった場合はレコードそのものを上書きする。

read レコード1件取得

payload.TableNameで指定したテーブルにpayload.Keyにプライマリーキーを指定して1レコードを取得する。

 

update レコード1件更新

createで同一プライマリキーを指定したときとは違って、レコードの一部を変更できる。

payload.Keyで指定したレコードの更新を行う。

プライマリキー属性は更新できないので、その場合はdeleteしてcreateしなおす必要がある。

また、AttributeUpdatesで処理を定義することもできるが現在は非推奨とされている。

まずUpdateExpressionに式を記入する。

以下の4つの式が使えるがSET, REMOVEの他は基本使わない。

  • SET – 属性の追加、更新
  • REMOVE – 1 つ以上の属性を項目から削除
  • ADD – 数値とセットデータのみサポートするが、通常はADD ではなく SET が推奨される
  • DELETE – セットデータ(HashSet)からString配列で指定したものを削除

次にExpressionAttributeNamesに属性名を定義。直接UpdateExpressionで指定してもいいが予約語とかぶらないように注意する。

同様にExpressionAttributeValuesに代入する値を定義。

ReturnValuesは以下から選ぶ。

  • ALL_OLD – 更新の発生前に表示されたように、項目全体が返される。
  • ALL_NEW – 更新後に表示されるように、項目全体が返される。
  • UPDATED_OLD – 更新の発生前に表示されたように、更新した値のみが返される。
  • UPDATED_NEW – 更新後に表示されるように、更新した値のみが返される。

 

DELETEは今回の例だと使えないため割愛。

書き方 : DELETE HashSet [“a”,”b”,…]

delete レコード1件削除

プライマリキーを指定してレコードを削除する。

list レコード一覧取得

テーブルを指定してレコード一覧を取得する。

 

HTTP RequestでDynamoDBを操作する

何をするか

外からAPIを叩いてデータをDBに保存してみたかったので試してみた。
プラットフォームはAWSオンリー。
以下のサービスを使って連携をしてみる。

  • API Gateway
  • Lambda
  • DynamoDB

DynamoDBの用意

まずAWSでNoSQL DBサービスのDynamoDBの準備をする。
AWSのサービスはそれぞれテスト機能があるので一番深いところから用意していくとトントン進む気がする。

  1. サービス一覧からDynamoDBを選択する
  2. テーブルの作成ボタンを押す
  3. 好きなテーブル名、プライマリーキーを設定する。今回はtestテーブル、キーをidにした。

以上でDBの準備完了。簡単!

Lambda, APIの作成

LambdaはAWSで用意されているコードの実行サービス。
Java,Nodejs,Pythonコードを実行可能(今回はNodejs)。
なのでここには処理の実行部分を書く。
今後処理の内容を弄るときには基本的にここをでロジックを書く必要がある。
今回やりたいことはBlueprint(色々セットで作ってくれるテンプレートのようなもの)で用意されているのでそれを使う。

  1. サービス一覧からLambdaを選択
  2. Create lambda functionボタンを押す
  3. Select blueprintからmicroservice-http-endpointを選択
  4. Nameは好きな名前を入れる(今回はtestLambda)
  5. RoleでBasic with DynamoDBを選ぶと新規ページが開く
  6. そのまま右下の許可を押す
  7. Roleの選択肢にlambda_dynamoが追加されているの選択(今後は直接これを選ぶ)
  8. 右下のNextボタンを押す
  9. microservice-http-endpointで作成した場合にはそのままAPIが作成できるのでmethodをPOST,SecurityをOpenに変えてNext
  10.  確認画面でOKなら完了

これで準備完了なのでテストしてみる。

Lambdaのテスト機能を使う

Lambdaの左上のTestボタンを押すとeventの中身を直接入力してテストできる。

以下のJSONを入力してテストすると実際にレコードが登録される。

DynamoDBのtestテーブルを見るとレコードが追加されているのが確認できる。

RESTクライアントを使ったテスト

ブラウザの拡張でREST APIテスト用のアドオンがあるのでそれで実際の動作を確かめる。

restclient

URL:APIエンドポイント
Method:POST
Body:

結果

Dynamoのtestテーブルを見ると2つのテストで入れたレコードが確認できる。

dynamo

このままだとURLをたたけば誰でもデータベース操作できてしまうのでLambdaの処理を絞ったり、APIに認証を設定したりする必要がある。

Qiitaのタグ別フォロー数と記事数で技術動向をつかむ

お手軽に技術動向をつかみたい。

気になった分野はさらっと試してみたい。

 

技術屋にとってはすでに英語は必須になっているとはいえ、いちいち英語の仕様書や掲示板を読むのはしんどいので日本語リファレンスの多さは重要だと思う。

 

最近はよくQiitaにお世話になってます。

デモやサンプルを動かす際の注意点なんかも多く記事になっており、何かしら新しく手をつけるときに非常に役立っている。

 

ちょっと思いついたのでQiitaのタグ別フォロワー数、記事数一覧でランキングを作ってみた。

 

Qitta傾向分析

 

最近データを取り始めたので、もう少したまってきたら可視化(グラフ化)してみたい。

 

WordPressの記事内でリンクをカード形式にして表示する

記事に何かしらのリンクを張るときに、はてなブログでブログカードと呼ばれているようなものを使いたい。

「Pz-LinkCard」というプラグインを使うことで実現できるようなので試してみる。

使い方はエディタで次のショートコードを書くだけ。

 

普通の記事にリンク

アイキャッチのある記事にリンク

外部リンク

 

見た目はCSSで変えられるようなのでとりあえずデフォルトの場合を画像で残しておく。

Pz-LinkCard1

ちょっと見た目に違和感がある。

URL部分とfaviconがうまく表示されていないのも気になるけどとりあえずOK。

 

WordPressの記事が検索結果ではHTTPS表示になる

Googleの検索結果から記事を開こうとするとURLがhttps始まりになり、SSL通信で接続しようとする。

この原因はGoogleがhttpsページを優先しているからとのこと。

検索結果でも優遇されるらしいのでいいことかと思いきや、ちゃんとSSL証明書を買って適応してないとページが表示される前に以下のような警告が表示される。

ssl

これを見ても気にせずアクセスする人がどれくらいいるのか。

対策としては WordPress HTTPS (SSL)プラグインをインストール、有効化して

  • Force SSL Administration(adminページをhttpsにする)
  • Force SSL Exclusively(SSLが有効でないときにhttpにリダイレクトする)

をチェックして保存する。

https

これで検索結果のhttpsもhttpにリダイレクトされるし、そのうち検索結果もhttpに変更されるはず。とりあえずこれで少し様子見。

過負荷でもないのにサイトにつながらないのはDDoS攻撃のせいだった

また落ちた

リソースの負荷もメモリ以外高くないのでネットワーク系かなーと思ってapache2,mysql,php-fpmを1から勉強してパラメータを調整しつつ様子を見るが変化なし。

topコマンドでリソースを見てもずっと同じようにphp-fpmが動いてるだけ。

あれ?ほぼアクセス0なのになんでこいつずっと動いてるんだ?

Apacheのログを見て驚愕する

なぜサーバログを最初に見なかったのか。

EC2.microに入れたこともあってリソース問題だと決め付けてかかったのが悪かった。

反省しつつ確認すると xmlrpc.php あてに大量のPOSTが送られていた。

3つのIPからきていたのでとにかくiptablesでIP拒否。

無事アクセスできるようになった。

原因と対策

xmlrpc.phpでググると色々出てきた。

どうも踏み台にされていたらしい。

対策としては

  • IP拒否  :  iptables -I INPUT -s xx.xx.xx.xx -j DROP
  • 対策プラグインを入れる  :  Disable XML-RPC Pingback
    • これはどうも最新版には対応していないみたいで仕事をしなかった
  • htaccess.conf で xmlrpc.phpにアクセスできない設定を追加する

感想

先入観ダメ。ゼッタイ。

「EC2 micro WordPress 遅い」みたいな調べ方では今回の原因にはたどり着けなかった。

きちんとログ見て原因の当りをつければすぐに見つかったので順序立てて調査しないといけない。

怪我の功名だけど今回の一件で色々チューニングの勉強ができたのは良かった。

WordPressでコードをいい感じに表示する

何をすればいいか

プラグインを入れることでエディタに機能が追加されるみたい。

紹介記事でよく出てくるのは以下の2つだった。

 

  • Crayon Syntax Highlighter
    • エディタにボタンが追加されて、コード挿入モードを経てコードを書ける

 

  • SyntaxHighlighter Evolved
    • 独自タグでコードを囲むことでコードを書ける([css]…[/css])
    • 紹介ページを見る限り使いにくそう
      • マウスドラッグで選択すると行数まで選択される
      • マウスドラッグでコピーできない
      • アクションボタンがコードにかぶって見にくい

 

というわけでCrayon Syntax Highlighterをインストール&有効化した。

実際に使ってみる

プログラム言語:default

プログラム言語:XHTML

エディタ上はどう見えるか

エディタだと上2つとも同じに見えるので、プレビューで確認する必要がある。

edit