あざらし備忘録。

音ゲー好きなウェッブエンジニアがいろいろ思った事やった事を書いていくブログです

超絶スクレイピングが楽になるサービスkimonoを使ってみた

スクレイピングをよしなにやってくれるようなサービスがないかなぁと思って探していたら kimono というサービスにめぐりあえて、非常に簡単かつパワフルで感動したのでご紹介しようと思います。

f:id:shiro_goma:20150911122415p:plain

Kimono : Turn websites into structured APIs from your browser in seconds

このkimonoの良さは以下の3つ。

  • 革新的なUI
  • ほしい情報だけ取り出せる
  • 定期実行可能

使い方を通じてこれらの良さを感じて貰えればと思います。

使い方

会員登録

まずは普通に会員登録を行ってください。無料です!

f:id:shiro_goma:20150911113606p:plain

インストール

登録後、画像のようなページに飛びます。

このページ内の kimonify とかかれた部分をブックマークバーにそのままドラッグ&ドロップしてください!

これでインストール完了です。

(この方法以外にも、トップページにブラウザの拡張ブラグインをインストールする方法もあります。お好みで。)

スクレイピングの設定方法

ここからがスゴイです。

ブックマークバーに登録した kimonify を「スクレイピングしたいページで」クリックしてください。

今回はインストールページでやってみます。

すると次のように画面のレイアウトが変わり、ヘルプページが表示されます。

f:id:shiro_goma:20150911114447p:plain

ひと通り読んだらcloseボタンを押して閉じてください。

スクレイピング対象の選択

画面上のスクレイピング対象にしたい文字や画像をクリックするだけですw

本当に簡単w

f:id:shiro_goma:20150911114811p:plain

今回は Learning kimono という見出しの文字をクリックしたので、そこがハイライトされました。

これでそこを抜き出してくれるようになりました。

先ほど選択したデータに名前をつけることも可能です。

左上にあるテキスト入力フォームの値を変更すれば、それが名前になるので、必要な場合は適宜編集してください。

取得できる予定のスクレイピング結果を確認

右上にある <> マークのボタンをクリックすると、取得予定の結果を確認できます。

基本このように取り出せると思って下さい。

f:id:shiro_goma:20150911115651p:plain

JSON形式やCSSRSS形式でも出力可能です。

基本の流れはこれでおしまい

あっけないほど直感的にポチポチしてたら欲しいデータが使いやすい形で出てきちゃいます。

色々遊んでみてください。

設定の保存

遊んでみた結果、欲しいデータが用意出来たら設定を保存します。

右上の Done ボタンを押してください。

f:id:shiro_goma:20150911120048p:plain

するとこのように画面が変わります。

設定を保存すると、なんと先ほど見ていたようなデータをいつでも取得できるようにAPI化してくれます。

適当にそのAPIに名前をつけましょう。適当で大丈夫です。あとで名前を見た時に何をスクレイピングしてるのかわかるようにつけたら良いです。

また、スクレイピングを行う頻度の設定も可能です。

執筆現在、以下のとおりの頻度で実行可能でした。

  • 手動実行(定期的な更新をしない)
  • 15分毎
  • 30分毎
  • 1時間毎
  • 1日毎
  • 1週間毎
  • 1ヶ月毎

取得するページの更新頻度に応じて上手く使い分けましょう。

入力が終わったら Create API ボタンを押したらもうAPIの完成です。

APIの設定

API作成完了後、API設定画面へのリンクが表示されるので、それをクリックするとAPIに関する設定のまとまったページへ飛びます。

基本は何も変えなくても大丈夫です。

例えば頻度の変更や、再度手動で取得したり、あとはこれまでの取得結果の履歴を見たりすることができます。

必要に応じていじってみてください。

また、APIの叩き方も紹介されています。かつ、curlに始まり色々な言語での方法が記載されていますので、参考にしてください。

以上!

とても簡単じゃないでしょうか?

正直文字で起こしたほうがわかりづらくなってるんじゃないかってくらいでしたw

本当いいプロダクトだと思うので宣伝の意も込めて書いてみました。

もうカジュアルにスクレイピングができる世の中になっていて、手軽で良いですね。

これならプログラミングの知識がない人でも簡単に行えますし。便利です。

ただ、くれぐれもスクレイピング対象のページに迷惑をかけないように、ルールを守って正しくスクレイピングしましょうw

有料版と無料版がありますが、全然無料版でも楽しめるプラン内容になっているので、ぜひ触ってみてください!

もっとリッチにスクレイピングしたい、と不満が出てきた時に有料版を検討してみてください。基本は無料版で大丈夫なはずです。

複数ウィンドウ存在するときでもいい感じにウィンドウ切り替えできるアプリHyperSwitchがとても便利だった[Mac][App]

なんでもっと早く出会えていなかったんだ!とちょっと感動したので記事に。

Macを使っていて、例えば Finder アプリで複数のウィンドウが立ち上がっている場合、 cmd + F1 を押すでもしないとウィンドウの切り替えができないですよね。

順番通りにしか移動できないし、移動するまでお目当てのものなのかわからないし...といった感じで不便に感じます。

そういった「同一アプリケーションで複数のウィンドウを持っている」ような状況でも快適に切り替えが出来るようになるアプリ、それがHyperSwitchです!!!

bahoom.com

https://bahoom.com/images/hyperswitch_1_777.png?1367403738

公式ページから持ってきたものですが、一覧の中にFinderアプリのウィンドウが2つあるのがわかるかと思います。

デフォルトの切り替え機能だと、こうはなりませんよね??

他にも、「現在フォーカスがあたっているアプリケーションのウィンドウ一覧」からウィンドウを選ぶこともできます。

これが使えると cmd + F1 でいちいちお目当てのウィンドウを探し当てることもなくいい感じにウィンドウ選択できますね。

一つのアプリケーションで複数のウィンドウを持つ事が多い人には、すぐ便利だと感じてもらえると思うので、説明はこの辺までにしておきます。

是非インストールしてみてください!

webpackを試してみた[JavaScript][webpack][超入門]

今回はjsを触っていて「requireとかってどうやってやるんだろう」とか「依存関係とかってどういう風に付き合っていくんだろう」と思って調べてみたらwebpackに行き着いたので、とりあえず使ってみたメモとして。

よく並んで耳にする BrowserifyRequireJS との比較は今回は行いませんmm (webpackが初めてなので!mm)

とりあえずwebpackが最後発というのはわかった。

webpackとは

JavaScript用のモジュール管理ツールです。

リソースの依存関係を解決して、複数ファイルをまとめたファイルを生成することができます。

コンパイルができるイメージでしょうか。

https://webpack.github.io/assets/what-is-webpack.png

jsだけでなく、cssや画像なども扱う事が可能なようです。

Symfony2を使っているので話を出すと、Symfony2でいうところのassets的な感じですかね〜。

なんとなく便利そうなのはわかったので使ってみる

インストール

簡単インストール。

npm install webpack --save-dev

チュートリアル

公式のやつをなぞって試してみます。

tutorials/getting-started

webpackの超基本的な使い方

jsファイルとしてentry.jsを、htmlファイルとしてindex.html をそれぞれ作成します。

entry.js

document.write("It works.");

index.html

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
    </body>
</html>

html内でbundle.jsというファイルが読み込まれていますね。知らない子ですね。

このbundle.jsがwebpackを用いてビルドされたjsファイルとなります。実際にビルドしてみましょう。

ビルド

webpack ./entry.js bundle.js

bundle.jsが生成されました!この状態でindex.htmlをブラウザで見てみると...?

f:id:shiro_goma:20150816192426p:plain

おぉ〜。It works.の文字。いい話。

これでentry.js以外にもファイルが増えたとてbundle.jsを読み込んでいれば勝手に反映されそうなので変更が楽で良さそうですね。

以上でとりあえずのwebpackの使い方はわかりました。

entry.jsが依存しているファイルを増やしてみる

依存解決を試してみましょう。

content.js を追加し、それを entry.js 内で読み込むようにしてみます。

content.js

module.exports = "It works from content.js.";

entry.js

document.write(require("./content.js"));

ビルド

webpack ./entry.js bundle.js

index.html を見てみると...?

f:id:shiro_goma:20150816193211p:plain

おぉ〜なるほど。ちゃんとcontent.jsで書かれた内容が表示されていますね。

依存関係をよしなに解決して動作させてくれています。素晴らしい!

ローダーを使ってみる

ローダー

webpackは、ローダーを追加してあげることで、jsの他にもcssなど、様々なファイルをビルド対象に取ることができます。

このローダーを使う例として、cssファイルをビルドに含めるようにしてみましょう。

ローダーの追加

ローダーの使い方一歩目
npm install css-loader style-loader --save-dev

cssを読み込むために必要なcss-loaderと、cssをスタイルに適用するためのstyle-loaderの2つをインストールします。

先ほどの例を、cssを用いるように変更してみましょう。

style.css
body {
    background: yellow;
}
entry.js
require("!style!css!./style.css");
document.write(require("./content.js"));

このように、ローダーを用いるときは!区切りで記述をします。

stylestyle-loaderを、csscss-loaderを表しています。

もちろんstyle-loaderのようにフルネームで書いても大丈夫です。

f:id:shiro_goma:20150822161630p:plain

ローダーを紐付けてビルドする

ビルド時にファイルの拡張子とローダーを紐付けることもできます。

webpack ./entry.js bundle.js --module-bind "css=style\!css"

この場合は読み込み時の記述は以下の様で大丈夫です。

entry.js
require("./style.css");
document.write(require("./content.js"));
コンフィグファイルを用いる

設定ファイルを用いてビルドすることもできます。

設定ファイルにはビルド対象のファイル(entry.js)や、出力先のファイル(bundle.js)だったり、ローダーのような設定を記述することもできます。

webpack.config.js
module.exports = {
    entry: "./entry.js",
    output: {
        path: __dirname,
        filename: "bundle.js"
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style!css" }
        ]
    }
};

設定ファイルを記述した場合は、ビルド実行はwebpack だけでOKです。

webpack

ファイル変更を検知して自動ビルドする

webpackのビルド時に --watch オプションを付けることで変更された時に自動的に再ビルドが走るようにもできます。

webpack --watch

このようにとても簡単にjsをビルドしながら操れるようになりました。これはハッピーになれそうですね!

導入までしんどい事がないので積極的に使っていこうとおもいます。

参考

今回のチュートリアルで触れた部分のコードはこちら。

github.com

npm installでローカルインストールしたライブラリのコマンドを使えるようにする[npm][JavaScript]

npmでライブラリをインストールするときに、-gをつけずにインストールをするとnode_modules下にインストールしたライブラリが入ります。

そのときにライブラリ側が提供しているコマンドを実行しようとした時、例えばwebpackだと

./node_modules/webpack/bin/webpack.js

みたいなところを実行しなくてはいけないのかな〜辛いな〜と思っていたらそんなことなく解消出来たのでメモ。

話は簡単で、実は./node_modules/.bin/というディレクトリ下に実行可能なコマンドは入っているので、そこにパスでも通してあげればグローバルに入れた時と変わらずコマンド実行できるようになりました。

export PATH=$PATH:./node_modules/.bin

とでもすれば解決できました。めでたしめでたし。

体調[自戒]

久々に体調を崩してしまったしちょっと良くなったと思ってアクティブに動いたらぶり返してしまって先週は散々だった。

体調微妙になったらとっとと会社休んで寝ろ。その方が結果的に時間短縮して復活出来るぞ。

今週は頑張るぞい(˘ω˘)

Vue.jsに入門してみた[JavaScript][Vue.js]

ちょっときっかけがあってVue.jsを初めてお勉強してみたので勉強メモ。 JS界隈、全体的に疎さがあるので、関連用語の説明も加えつつ書いてみます。

Vue.jsとは

Vue.js はインタラクティブな Web インターフェイスを作るためのライブラリ。 MVVMパターンのViewModelレイヤに注目していて、ViewとModelを双方向バインディングによって接続しています。

特徴

Vue.jsはざっと以下のような特徴があります。

公式ドキュメントも全て日本語化されていて、ありがたやといったところでした。 公式ドキュメントの物量としてもざっと読むだけなら全然1日かからないくらいだったので本当学習コストは低めだなぁと感じました。

MVVMパターンとは

MVVMパターンとは、Model/View/ViewModelの3つの責務にGUIアプリケーションを分割するパターンのことです。

その中でVue.jsはViewModelレイヤを担っていますよっていうところですね。

f:id:shiro_goma:20150801174627p:plain

Vue.js公式からもってきている画像ですが、すごい関係がスッキリまとまっていて良いです。

双方向バインディングとは

双方向データバインディングとは、データの変更があったらUIの表示を更新し、UIの変更があったらデータの更新する、といった処理を自動的に行う機能を指します。

これができているとViewで表示される内容とModel内で処理されている内容が同期がとれて良いですね。

Vue.jsはこの双方向データバインディングをシンプルに行うことに重点を置いています。

インストール

インストール方法は公式ドキュメントにお任せしますmm

jp.vuejs.org

Vue.jsの提供する機能

Vue.jsとしてのまず押さえる必要のある機能は大まかには以下に並べるくらいです。

以下のサンプルに沿って必要知識をまとめようかと思います。

インスタンスプロパティ

基本中の基本としてはeldataが挙げられます。

el

Vueインスタンスが管理する対象のDOM要素です。 View部分の担当です。

data

Vue インスタンスが監視しているデータオブジェクトです。 Model部分の担当です。

f:id:shiro_goma:20150801201046p:plain

ざっくりとした図ですが、赤枠がel関連、青枠がdata関連です。

elで監視対象を指定して、その監視範囲に対してdataを用いてほげほげする感じですね。 このようにhtmlはあくまでフレームとして用いて、実データの方はjsの方に持たせるといった分担が綺麗にできるようになりスッキリしますね。

他にも何種類かインスタンスプロパティは用意されているのでご参考くださいmm

インスタンスプロパティ - vue.js

ディレクティブ

ディレクティブとは、DOM 要素に対して何かを実行することをライブラリに伝達する、マークアップ中の特別なトークンです。

Vue.jsを触るようになるとよくよく目にするようになります。

f:id:shiro_goma:20150801202403p:plain

赤枠がディレクティブ、青枠がそのディレクティブが対象とするdata等が入ってきます。

青枠のところは用いるディレクティブによって色々変わってきます。

例えば、 v-onディレクティブはclick:から始まりますが、これはv-onディレクトリ固有のものになっていたりします。

APIリファレンスをよく読んで正しく使うようにしましょう。

ディレクティブは、大きく以下の4種類に分類されます。

  • リアクティブディレクティブ
  • リテラルディレクティブ
  • エンプティディレクティブ
  • カスタムディレクティブ

リアクティブディレクティブ

リアクティブディレクティブは、それ自身を Vue インスタンスのプロパティやインスタンスの文脈の中で評価される表現にバインドすることができます。 配下のプロパティや表現の値が変更されたら、それらのディレクティブの update() 関数が同期的に呼ばれます。

リテラルディレクティブ

リテラルディレクティブは、データバインディングを生成せず、単に文字列リテラルを属性値として取ります。 その要素の値を素の文字列として取り扱い、何ともバインドしようとしません。 このディレクティブが行うのは、文字列の値を bind() 関数に渡して実行することだけです。 リテラルディレクティブはその値の中で Mustache 表現を使用できますが、それらの表現は最初のコンパイルの際に一度だけ評価され、データの変更に対して反応しません。

エンプティディレクティブ

エンプティディレクティブは、属性値すら期待せず、単純にその要素に何かを一度きり行います。

このように色々なディレクティブがあるので、詳細は以下のAPIリファレンスをご参照の事。 恐らくこのリファレンスに頻繁にお世話になりながらコードを書いていく感じになるのかなと思います。

jp.vuejs.org

カスタムディレクティブ

カスタムディレクティブは、データの変更に伴い DOM がどのように変更されるかを定義することができる仕組みです。 有り物だけではちょっとつらいみたいな状態になった時に拡張出来る仕組みです。

jp.vuejs.org

Mustacheスタイルのバインディング

{{ }} これですw

mustache は口ひげの意で、{が口ひげっぽいかららしいですね。

mustache.jsというテンプレートエンジンと同様の構文ですね。

ざっくりいうと変数展開ができます。

f:id:shiro_goma:20150801204413p:plain

フィルタ

フィルタは、本質的には「値を取り、加工し、加工した値を返す」関数です。マークアップ内ではパイプ(|)で表され 、一つ以上の引数を続けることができます。

View を更新する前の生の値を処理するために使われる関数です。

変数に対してある処理を行ってから反映をさせることができるようになります。

f:id:shiro_goma:20150801204734p:plain

デフォルトでは以下のフィルタが用意されています。

  • capitalize
    • 先頭文字を大文字にする
  • uppercase
    • 全部大文字にする
  • lowercase
    • 全部小文字にする
  • currency
    • 引数に好きな通貨単位を取る(ex. $)
  • pluralize
    • 引数に取った値を複数表記にする(ex. item => items)
  • json
    • 引数にインデント幅を取ってjson表記にする
  • key
    • v-onディレクティブとセットで使える
    • 「エンターキーが押されたとき」みたいなのを表現できる
  • filterBy
    • v-repeatディレクティブとセットで使える
    • 引数にフィルタリング条件を取って元配列の内容をフィルタリング出来る
  • orderBy
    • v-repeatディレクティブとセットで使える
    • 引数にソート条件を取って元配列の内容をソート出来る

カスタムフィルタ

コレ以外にもフィルタ欲しい...ってなった時にはカスタムフィルタを定義することも可能です。

Vue.filter('reverse', function (value) {
  return value.split('').reverse().join('')
})

のような感じで定義可能です。

その他

他にも色々用意されてます!

本当に最小限といった形で入門記事を書いてみましたが、今回出した例の範疇を越えて行くと色々な機能も他にもあります。

あたりは今回は触れなかったので追々触れられたらいいな〜と思ってます。

でもこの辺りまでしっかり見ていったとしても、大して学習は時間はかからなさそうだなぁという感想なので、本当に軽めな良いフレームワークだなぁというのが所感です。

良い感じの例も公式で準備してくれてます:)

jp.vuejs.org

ここに置いてあるソースとかを眺めてみても勉強になるかなと思います!

基本は公式をみてれば良さそう

公式ドキュメントがしっかりしているので、公式ドキュメントと仲良くなればおおかた作っていけるかなぁという感触があります。

jp.vuejs.org

自分もしっかり読んで使っていこうと思います!

第一印象としてはすごく使い始めやすそうだなぁという感じだったので、引き続きちょっと触って行きたいと思います!

DoctrineCacheBundleでMemcachedを使おうとした時にハマった話[Symfony2][DoctrineCacheBundle][Memcached]

Symfony2プロダクトでMemcachedを使おうとした時には、DoctrineCacheBundleが使えます。

github.com

基本的にはカジュアルにコンテナから取り出せて便利〜って感じだったのですが、ElastiCacheを使おう〜って思った時にガンハマりしたので備忘録として。

どうハマったか

端的にいうと、「yaml記法で書かれた設定ファイルのホスト名がよしなに書き換えられてしまう」せいで、ElastiCacheにつながらない、という問題に直面して、苦労したお話です。

原因がわからず詰まっていた

どう書き換えられたか

github.com

このREADMEの

# app/config/doctrine_cache.yml

doctrine_cache:
    providers:
        my_memcached_cache:
            memcached:
                servers:
                    memcached01.ss: 11211
                    memcached02.ss:
                        port: 11211

を参考にして、設定ファイルを以下の様に書いていました。

# app/config/doctrine_cache.yml

doctrine_cache:
    providers:
        my_memcached_cache:
            memcached:
                servers:
                    hoge-fuga-01.abcdef.0001.apne1.cache.amazonaws.com: 11211
                    hoge-fuga-02.abcdef.0001.apne1.cache.amazonaws.com: 11211

的な感じで。

これがなんと、コンテナから取り出した時にはホスト名がそれぞれ

hoge_fuga_01.abcdef.0001.apne1.cache.amazonaws.com
hoge_fuga_02.abcdef.0001.apne1.cache.amazonaws.com

に自動的に書き換えられた状態でセットされてしまう、というものでした。 yamlの仕様かYmlParserの仕様かDoctrineCacheBundleの仕様かContainer周りの仕様か追いきれてないですが、とりあえずこうなってしまうようですorz

どう解決したか

READMEのxmlの例を見て推測しつつ、次のようにやってみたら出来ましたw

# app/config/doctrine_cache.yml

doctrine_cache:
    providers:
        my_memcached_cache:
            memcached:
                servers:
                    server1:
                        host: hoge-fuga-01.abcdef.0001.apne1.cache.amazonaws.com
                        port: 11211
                    server2:
                        host: hoge-fuga-02.abcdef.0001.apne1.cache.amazonaws.com
                        port: 11211

この様にするとホスト名を文字列的に明示してかけるのでよしなに書き換えられる事なく無事つなげることができました。

原因がわかってみれば大したことはなかったのですが、なかなか問題の切り分けがしづらく苦戦しました...

ということで、DoctrineCacheBundleを使ってMemcachedを扱うときは、「ホスト名やポート名は明示するようにしましょう」という備忘録でした。