詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

GitHub でイシューからイシューを作るときに便利な userscript

とくに GitHub を使って仕事をしていると、あるイシューからそのサブイシューを生成する機会がよくあって、そういう時はサブイシューから親イシューを(#765 のようにして)参照しておくと便利なのだけれど、イシューをまとめて整理しているときにはこの細かい作業が面倒。そこで userscript を書いた。

github-userscripts/refer-issue-when-creating at master · motemen/github-userscripts · GitHub

挙動は簡単で、GitHub 上のイシューや Pull Request のページ内にある「New Issue」ボタンをクリックしたとき、イシュー作成フォームの本文やタイトルに、もともとのイシューを参照するような内容がフィルインされるというもの。本文にはイシュー番号、タイトルには元のイシューの名前が入ります。このへんは人の好き好きだと思うので、各自カスタマイズするとよいと思う。また、ボタンのクリック時に選択していた内容がタイトルに付与されるというのもおまけでついてます。

以下のアニメーション GIF を見ればわかりやすい。

f:id:motemen:20150123135611g:plain

いつもどおり、利用するには chrome://extension に .user.js をドラッグ&ドロップすればよい(Chrome の場合)。どうぞご利用ください。

イシュー管理にお役立ち。GitHubのIssue/PRの状態が一目で分かるバッヂ

f:id:motemen:20141026214110p:plain

こんな感じに使えますっていうウェブアプリ+Chrome 拡張のはなしです。(ちなみに例はこれ

GitHub ではイシューへのリンクが "#829" という風に番号になって表示されますが、イシューをバリバリ使っていてこれらの間の参照が多く発生するような場合に、これって誰がやってるんだっけ、もう終わったんだっけ、と分からなくなることが多々ありますよね。こういう時、文中に画像で埋め込まれているとパッと見て分かりやすい。

デモ

http://github-issue-badge.herokuapp.com/

にデプロイしてあります(トップページは GitHub Pages にリダイレクトされますが)。

次の画像: motemen/test-repository#1http://github-issue-badge.herokuapp.com/badge/motemen/test-repository/5)が正しく表示されればオッケー。403 と出る人は /auth を訪れて OAuth 認証してください。プライベートリポジトリにまで権限を与えたくない場合は /auth?only=public へどうぞ。

http://github-issue-badge.herokuapp.com/badge/:owner/:repo/:number という URL で、SVG のバッヂ画像を配信しています。バッヂのパーツは左からイシュー番号、ステータス(open/closed/merged)、作成者もしくは担当者、それからラベル(の色)となってます。

以下に書くように、自前でデプロイするのも簡単です。その場合は GitHub:Enterprise 用に立てることもできます。

自前でデプロイする

リポジトリはこちら: https://github.com/motemen/github-issue-badge

お好きな方法を選んでください:

  • 一番簡単なのは Heroku にデプロイする: Deploy
  • もしくは Fig を使って: fig up
  • または普通に rack アプリとしてデプロイ。

設定

環境変数として以下が指定できます。(app.json に詳しいです)

GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET

画像にアクセスするクライアントに OAuth 認証させて API を使う場合はこのふたつを設定してください。

GITHUB_OAUTH_ACCESS_TOKEN

アクセストークンを予め生成しておき、これに設定しておくと、クライアントはいちいち OAuth 認証しなくてもバッヂを見ることができます。GHE や小さな組織で利用する場合はこれで十分です。

GITHUB_API_ENDPOINT

GHE を使う場合は指定してください。http://ghe.example.com/api/v3/ とか。

REDIS_URL

Heroku か Fig を利用する場合は不要。

Chrome 拡張

で、冒頭のスクリーンショットのようにリンクを画像に差し替えるためには GitHub の Content-Security-Policy を書き換えてやる必要があり、拡張にしてます。GitHub イシュー内でイシューへのリンクを画像に差し替える拡張。

https://github.com/motemen/chrome-Embed-GitHub-Issue-Badges

GHE ユーザや個人でデプロイした人もこの拡張を使えるように、GitHub および github-issue-badge の URL をカスタマイズした拡張をビルドできるようになってます。README にも書いてますが、src/ts/config.ts を

export var badgeOrigin  = 'http://github-issue-badge.yourcompany.example.com';
export var githubOrigin = 'https://github.yourcompany.example.com';

という風に書き換えて、

npm install
npm run build

すると build/ ディレクトリ以下にその設定に応じた拡張が生成されます。これを chrome://extensions から追加してください。

Fig

Fig 使ってみたけど便利だった……。というか Redis とか Ruby とかの公式イメージが配布されてるのが便利で、とくに Ruby は FROM ruby:2.0-onbuild などとするだけで bundle 済みのイメージが簡単に作れてしまう。ちょっとしたアプリの配布とデモにはとても役立ちそう。

まだmechanizeで消耗してるの? WebDriverで銀行をスクレイピング(ProtractorとWebdriverIOを例に)

今日はスクレイピングの話をします。

今回のターゲットは三菱東京UFJダイレクト。金融機関もウェブサービスを提供するようになり、金にまつわる情報を電子化しやすくなりましたが、かれらが API を提供しているわけではないので、私たちのほうで取得・加工をしてやる必要があります。今やウェブサイトであれば当然のように JavaScript を使っているわけなので、いわゆる mechanize、つまり HTML の解釈をおこない、リンクのクリックやフォームの送信をシンプルに実装するようなやり方でのスクレイピングはすでに無理筋だといえます。

f:id:motemen:20140930200107p:plain

もちろん今日においてはブラウザオートメーションという方法がすでにありますので、これを利用してやれば、なんの憂いもなく実際に人間が使うようなブラウザをプログラマティックに操作することができます。現在は Selenium WebDriver がデファクトで、これが使用する JSON Wire Protocol というプロトコルを通じて様々なブラウザを操作できます。

JSON Wire Protocol の実装はいろいろな言語にありますが、今回は言語に JavaScript を利用することにして、クライアント側のライブラリとして ProtractorWebdriverIO をそれぞれ使ってみます。個人的に、過去には CasperJS というライブラリを利用してスクレイピングをしていました。これは PhantomJS という GUI なしの WebKit によるブラウザ実装を操作するライブラリですが、上に挙げたような方法で PhantomJS に限らないブラウザを操作できる(PhantomJS 自身も Ghost Driver という名前で WebDriver に対応しています)現在、PhantomJS(と SlimerJS)しか使えない CasperJS を選ぶ理由はなさそうです。

さて、Protractor と WebdriverIO それぞれについて見ていきます。

Protractor

http://angular.github.io/protractor/

サンプル

example-scrape-websites/protractor at master · motemen/example-scrape-websites · GitHub

git clone してこのディレクトリで以下のコマンドを実行すると、Chrome が自動的に起動して三菱東京UFJダイレクトにログインし、残高を表示した上で先月の残高を YYYY-mm.tsv ファイルに書き出してくれます。

環境変数 MUFG_ID, MUFG_PASSWORD にそれぞれ必要な値を与えておいてください。

npm install
npm run scrape-mufg

特徴・長所

  • もともと AngularJS 用の E2E テストライブラリ。
  • Selenium オフィシャルのライブラリ WebDriverJS の上に実装されている。
  • JS テストフレームワーク(Jasmine/Mocha/Cucumber.js)と組み合わせることを前提としている。
  • WebDriverJS がそうだからなのだけど Promise をいい感じの順番で実行してくれるので、メソッドチェインを長々とつなげなくてもすむ。
  • Selenium 側の実装のインストールや起動まで自動でおこなってくれて便利。
    • bin/webdriver-manager というのがいい感じにやってくれる。
  • protractor 経由で起動するとテストファイルの内部で browser というグローバル変数が定義され、これを通じて Protractor(や WebDriverJS)の API を使用できる。

Protractor で AngularJS を使っていないサイトを対象にする

Protractor は AngularJS 用のライブラリなので、普通に使おうとすると AngularJS の読み込みを待ってから操作をはじめようとしてしまう。これを回避するには以下のようにしてやればいい。ただしいい感じに条件が整うまで実行を遅らせてくれるみたいな機能が使えなくなるので注意。

browser.ignoreSynchronization = true;

セキュリティに気をつける

普通に ChromeDriver 経由で Chrome を起動すると、

f:id:motemen:20140930195220p:plain

サポートされていないコマンドラインフラグ --ignore-certificate-errors を使用しています。これにより、安全性とセキュリティが損なわれます。

というバーが表示される。銀行のサイトにアクセスするのにセキュリティを損なっては意味が無いので、protoractor.conf.js で Chrome に与えるオプションを制御して、当該のフラグを落とすということをしています。

WebdriverIO

http://webdriver.io/

サンプル

example-scrape-websites/webdriverio at master · motemen/example-scrape-websites · GitHub

動かし方は Protractor の場合と同様です。ただしブラウザは Firefox が起動すると思う。

ちなみにこっちの方はお知らせを自動で読む機能はないです。お知らせが出る状態を意図的に作り出せないので……(だれか口座くれたら確認します)

特徴・長所

  • JSON Wire Protocol を叩くための JS のライブラリといったところ。
  • メソッドチェインとコールバックで操作を記述する。
  • テストに関する機能はないので、自分で好きなものを使える。
  • メソッドごとにソースコードのファイルが分かれていて、読みやすい(大事だと思う)。
  • Selenium の起動なども自分でやる必要がある。

総括

Protractor 便利だな〜と思ってたけど機能もりもりすぎてかえってつらい。どちらにしろ JS で書くと Promise/コールバック地獄になるのは間違いないので、ちょっと面倒なところは面倒。スクレイピングを日常使いするなら、Selenium に与える設定でブラウザを PhantomJS に置き換えるよう指定すれば headless に実行できるので便利です。

JavaScript (node)から WebDriver を扱うものには他にもこんなライブラリがあるそうです:

  • Nightwatch.js
    • テストフレームワークも兼ねているもよう。
    • コールバックをつなげていくスタイル。
  • WD.js
    • インタラクティブシェルが付属してて便利そうだった。
    • コールバックや Promise など複数のスタイルで操作を組み立てることができる。

この手の話をまとめだすと本一冊ぶんになっちゃうな〜と思ってたら、つい最近こんな本が出てました。具体的なテクを知るにはちょうどよさそうですね!

実践 Selenium WebDriver

実践 Selenium WebDriver

追記

Selenium Webdriverでのスクレイピングについて。利用するモジュールの話が色々あって、とても参考になる。/こちらも宜しくw Selenium Webdriverの例も載せてる。 http://www.amazon.co.jp/dp/4797380357 - dkfj のコメント / はてなブックマーク

以下の本にも紹介があるそうです。

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

はてなで一緒に働きませんか?