プログラマでありたい

おっさんになっても、プログラマでありつづけたい

2014年1月5日まで!!Amazon Kindle本の冬のセール。私のお薦め本と買った本

 今更ながら知ったのですが、2014年1月5日までAmazonがKindle本の冬のセールをやっています。セール対象は、全部で1,298冊です。幾つかのお勧めの本があるのと、このセールで私が買った本の紹介をします。

私が読んだことがあるお薦め本



モーセと一神教
 実は精神分析家として有名なフロイトの、最晩年の著書です。宗教論や歴史書として、興味深いです。前回勧めた際に、Kindle版がずいぶん易いと感じてたのですが、セール中だったのですね。


売り方は類人猿が知っている
 行動経済学を下敷きに人類進化の歴史から、マーケティングやセールを考察しています。軽くて読みやすいです。


ウェブはグループで進化する
 バズ・マーケティングやインフルエンサー・マーケティング論について、現実との乖離を感じていました。この本を読んで、その感覚は間違っていないとわかりました。著者はGoogle+とFacebookの開発者で、Google在籍時代にGoogleから出版をストップさせられ、Facebookに移籍後に出版されたいわくつきの本です。ソーシャルネットワークを知り尽くした人が書いた本で、説得力が違います。

今回のセールで買った本



一九八四年
 オーウェルの名作。ビッグブラザーのもとに、管理社会となった世界を描くSFです。Appleの伝説的なCM「1984」もこの本が下敷きになっています。IBMの独占を打破するのはAppleという構図です。あらすじしか知らないので、読んでみます。


ランチェスター思考
 最近、名前をよく聞きます。私は中身を全く知らないので、このセールを機会に読んでみることにしました。競争戦略論のようです。


「パレスチナが見たい」
 中東問題の中心地、パレスチナ。歴史的な経緯は知っていても、今現在の実情は殆ど知りません。パレスチナに住んでいたふつうの人が綴った生活史を読むことで、パレスチナの日常が垣間見れないかと読んでみることにしました。


0歳からの母親作戦
 ソニーの創業者の一人、井深さんの教育論です。昔読んだような気がしますが、あらためて読んでみることにします。0歳児教育については鵜呑みする気はないですが、名経営者の教育論ということで興味があります。


里山資本主義 日本経済は「安心の原理」で動く
 昨年来、日本の森林管理について興味を持っています。その中で里山というのは、大きなテーマの1つです。経済の中で語られているということを期待して読んでみます。


See Also:
今まで読んで良かった本 100冊
「ウェブはグループで進化する」を読みながら、シェアされるポップを考えた
ジャレド・ダイアモンドの文明の崩壊。森林破壊と和歌山と
意外に知らない日本の森林の話
この著者は売れる本の書き方を知っている。 売り方は類人猿が知っている


あらためてRuby製のクローラー、"anemone"を調べてみた

 3年ほど前に、Ruby製のクローラー"anemone"を紹介しました。その当時から完成度が高く、Rubyでクローラーを使う場合はanemoneを利用してきました。最近、他に新しくて良いのがないか調べましたが、機能面の網羅性という意味でanemoneを超えるものは見つけられませんでした。そこで改めてanemoneのソースを読んでみたところ、クローラーが必要とする機能を必要最小限で実装され、やはり中々良い出来です。冬休みの宿題ではないですが、勉強の意味を兼ねてソースを追っていくことにします。

Anemoneが利用しているライブラリ一覧



 anemoneが利用しているライブラリは、4種類に分類できます。

  • Ruby標準or一般的なライブラリ
  • データ取得で利用しているライブラリ
  • データ解析で利用しているライブラリ
  • データ保存で利用しているライブラリ

この分類別に構造をみるとわかりやすいので、順番に追っていきます。

Ruby標準or一般的なライブラリ


require 'rubygems'
require 'delegate'
require 'forwardable'
require 'optparse'
require 'thread'

 delegateとforwardableは、メソッドの委譲を行うruby標準のライブラリです。optparseは、コマンドラインのオプションを取り扱うためのライブラリです。threadは並行プログラミングを行う為のライブラリです。特筆すべきところは、余りありません。唯一気になったのは、delegateとforwardableの併用についてです。anemoneでは、cookie_storeの実装の部分のみdelegateを使い、データ保存の部分で各ストレージ(kyoto_cabinet,pstore,tokyo_cabinet)についてはforwardableを使っています。この2つのモジュールの選択のポイントについては、よく解っていません。ストレージ機能の実装時期が2年ほど後ということもあり、流儀が変わった可能性もあります。もしくは、移譲について明示的に指定するかどうかの所で、移譲するメソッド数による判断の可能性もあります。

データ取得機能の構造


require 'net/https'
require 'webrick/cookie'
require 'robotex'

 データ取得機能については、core.rbとhttp.rbで実装されています。データ取得の為のライブラリとしては、通信部分には標準のnet/httpsを利用しています。cookieの取扱は、webrick/cookieを利用しています。名前から解るように、Webサーバー用フレームワークのWebrickを利用してCookieの処理を行っているのですね。そして、robotexです。このライブラリは、anemoneの作者であるChris Kiteによるライブラリです。robots.txtの判定を別モジュールとして外出しにしています。この部分は、自分でクローラーを作成する場合にも利用出来ます。使い方は、anemoneでは次のようになっていました。


デフォルトの設定。robots.txtに従わないようになっています。

    # don't obey the robots exclusion protocol
    :obey_robots_txt => false,


引数でrobots.txtに従うように設定した場合、変数@robotsを作成しています。

    @robots = Robotex.new(@opts[:user_agent]) if @opts[:obey_robots_txt]


Robotexモジュールの使い方は、次の通りです。robots.txtに従う場合、Robotexモジュールのallowdメソッドでリンク先を取得可能かの確認をしています。(再度オプションの:obey_robots_txtを見に行っているのは、微妙な気がします。)

  def allowed(link)
    @opts[:obey_robots_txt] ? @robots.allowed?(link) : true
  rescue
    false
  end


このallowdメソッドが、実際使われている所です。visit_linkメソッドでAnd条件で訪問可能か確認しています。

    def visit_link?(link, from_page = nil)
      !@pages.has_page?(link) &&
      !skip_link?(link) &&
      !skip_query_string?(link) &&
      allowed(link) &&
      !too_deep?(from_page)
    end


 この実装であれば、同一サイトでも都度robots.txtを確認するような気がします。念の為、Robotexモジュールの実装も確認してみます。結論的には、一度確認したサイトについては、robots.txtの再取得をしないような作りになっています。一安心です。

  def allowed?(uri, user_agent)
    return true unless @parsed
   〜略〜
  end

データ解析機能の構造


require 'nokogiri'
require 'ostruct'

 データ解析機能については、page.rbで実装されています。そして殆どの処理の実態は、nokogiriでのパースです。その為、anemoneの利用元の方で、nokogiriを使って自由に加工出来ます。
ex)利用例

Anemone.crawl("http://www.example.com/") do |anemone|
    anemone.on_every_page do |page|
      title = page.doc.xpath("//head/title/text()").first.to_s if page.doc
      puts title
    end
end


 HTML解析の中のリンクの検索については、aタグ中のhrefを検索しているだけのようです。FormやJavaScript等で飛び先を指定しているのは、取れません。クローリングで迷惑を掛けることを防止するには、このaタグのみ取得する実装が賢明だと思います。

  def links
    return @links unless @links.nil?
    @links = []
    return @links if !doc

    doc.search("//a[@href]").each do |a|
      u = a['href']
      next if u.nil? or u.empty?
      abs = to_absolute(u) rescue next
      @links << abs if in_domain?(abs)
    end
    @links.uniq!
    @links
  end

データ保存機能の構造


require 'kyotocabinet'
require 'mongo'
require 'tokyocabinet'
require 'pstore'
require 'redis'
require 'sqlite3'

 anemoneは、取得したデータの保存先の選択肢が豊富です。初期は、sqlite3のようにRDBMSや、pstoreなどの標準のファイルオブジェクトのみでした。いまでは、tokyocabinet/kyotocabinet・redisのようなキーバリューストアや、mongoDBのようなNoSQLにも対応するようになっています。履歴を見ていると、利用者からのPullRequestがマージされている模様です。
 構造的には、anemone/storageにストレージごとの実装を追加するという形になっています。割と簡単に追加できそうなので、試しにAmazon S3を利用したタイプでも作ってみようと思います。

まとめ



 ざっとanemoneの構造を確認してみました。ページ取得の部分は、coreの部分と密な結合になっているようです。反対にページ解析やデータ保存については、比較的疎結合になっています。もともと、ページ取得部分だけ取り替え可能を知りたくて調べました。http.rbを呼び出している部分を置き換えれば出来なくもなさそうですが、それよりもページ解析機能やデータ保存機能を移植する方が楽そうです。
 anemoneは比較的小さなライブラリですが、色々な要素があります。ソースを順番に読んでいくと、中々勉強になりました。興味がある方は、時間があるときに一度読んでみてはいかがでしょうか? enjoy!!

PR
anemoneの解説を含めて、Rubyによるクローラー開発の本を書きました。
クローラーの概念から実際の構築・運用手順を網羅しています。


See Also:
オープンソースのRubyのWebクローラー"Anemone"を使ってみる
JavaScriptにも対応出来るruby製のクローラー、Masqueを試してみる
複数並行可能なRubyのクローラー、「cosmicrawler」を試してみた


参照:
chriskite/anemone · GitHub
Rubyist Magazine - 標準添付ライブラリ紹介 【第 6 回】 委譲
anemone RDoc
PythonとかScrapyとか使ってクローリングやスクレイピングするノウハウを公開してみる! - orangain flavor


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

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

複数並行可能なRubyのクローラー、「cosmicrawler」を試してみた

 最近のRubyのクローラーは、EventMachineを使って並列化するのが流行のようです。EventMachineは、非同期処理をお手軽に実装できるフレームワークです。Rubyのスレッド機能との違いは、Reactorパターンを使いシングルスレッドで実装している点です。こちらのブログが詳しいので参考になります。 「見えないチカラ: 【翻訳】EventMachine入門
 EventMachineを使うと、イベント・ドリブンの処理を簡単に実装出来ます。使い方は簡単ですが、通常の同期処理やスレッドをつかった処理に比べると、どうしてもコードの記述量は多くなります。今回の例である並列化してクローラーを走らせるという用途であれば、短時間で多くのサイトにアクセスするのが目的です。イベント・ドリブンで並列化処理を実装するのが目的ではないはずです。その辺りの面倒くさい処理を実装したライブラリがcosmicrawlerです。中身の実装を見てみると、非常にシンプルで解りやすいです。通り一遍ですが、インストールして試してみました。

cosmicrawlerのインストールとサンプルソース



 まずはcosmicrawlerのインストールですが、gem install cosmicrawlerだけで出来ます。直接依存するモジュールとしては、eventmachineとem-http-request、em-synchronyの3つです。付随的にaddressable、cookiejar、em-socksify、http_parserがインストールされます。

 それでは、サンプルソースを見てみましょう。公式にあったサンプルの取得先を、はてなのURLに変えただけです。

require 'cosmicrawler'

Cosmicrawler.http_crawl(%w(http://b.hatena.ne.jp/hotentry/it http://b.hatena.ne.jp/hotentry/life)) {|request|
  get = request.get
  puts get.response if get.response_header.status == 200
}

 実行してみると、すぐに結果が出てくると思います。取得するURLの付与の部分を作りこめば、すぐに使えそうな印象です。

クローラーの機能を考える



 前回、Masqueを紹介しました。Masqueは、Capybaraを使いJavaScriptの画面にも対応出来るというのが特徴です。今回のcosmicrawlerは、並列処理で高速化できるのが特徴です。どちらも、データを取得するという機能に特化したクローラーです。


 クローラーの主な機能としては、以下の3つがあります。

  • データ取得 … データをダウンロードする機能。robots.txtに従うかの判断も必要。
  • データ解析 … HTMLをパースする機能。HTML中からリンクを抽出して、再帰処理などにも利用する
  • データ保存 … 取得したデータを保存する機能。ファイルの他に、RDBMSやNoSQLを使うパターンもある。


 上記の機能を全て揃えているRubyのクローラーのライブラリとしては、今のところはanemoneしか知りません。一方で、データ取得以外の部分については、それぞれのクローラーが独自で実装する必要性は薄いです。例えば、robots.txtで禁止されているかのチェックは専用のライブラリがあれば良いし、HTML中からURLを抜き出して再帰処理する部分もライブラリとして外出し出来そうです。またHTML解析の部分も、NokogiriなどのHTMLパースのライブラリを使うことが多いです。この辺りを疎結合に使えるパターンを思案中です。あるいはAnemoneをクローラーのフレームワークとみなして、データ取得部分のみを切り替えられるように変更を加えるのも面白いかもしれませんね。


See Also:
オープンソースのRubyのWebクローラー"Anemone"を使ってみる
JavaScriptにも対応出来るruby製のクローラー、Masqueを試してみる
あらためてRuby製のクローラー、"anemone"を調べてみた


参照:
Rubyで複数並行なクローラをすっきりと書けるライブラリ「cosmicrawler」をgemとして公開した
見えないチカラ: 【翻訳】EventMachine入門
PythonとかScrapyとか使ってクローリングやスクレイピングするノウハウを公開してみる! - orangain flavor


Rubyによるクローラー開発技法

Rubyによるクローラー開発技法

Spidering hacks―ウェブ情報ラクラク取得テクニック101選

Spidering hacks―ウェブ情報ラクラク取得テクニック101選

2014年の目標

 新年明けたので、忘れないうちに今年の目標を書いておきます。公開しても当たり障りのないものだけですが。。。

  • 本100冊&記録につける

 ⇒記録を付けるのがポイントです。

  • 文を書く力の向上

 ⇒今まで人に読まれることを意識して書いていませんでした。今年はその辺りを意識して、正しい&読みやすい文章をマスターすべく方法を考えます。

  • iPhone,iPadアプリ2本作成

 ⇒レッドオーシャンの、道案内アプリと計算機アプリを考えています。

  • Androidアプリ1本作ってみる

 ⇒作ったことがないので、1本作ってみたいです。内容は既存のiPhoneアプリの焼き直し予定です。

  • Webサービスを公開する(1件)

 ⇒ワインを共有するサービス

  • DevLoveコミュニティに参加

 ⇒昨年はAWSコミュニティに参加しました。今年はDevLove系に参加したいです。

  • ブログアクセス月100,000件

 ⇒現状5〜6万/月なので、抜本的にやり方を変えないと無理でしょうね。

  • ワインエキスパート資格の取得

 ⇒ワインブロガー目指してw


泡沫の夢にならぬよう、実現目指します。

2013年、Amazonアソシエイト結果 書籍編

 2013年の振り返り中です。第二弾は、書籍編です。
2013年は個別に本の紹介の記事を殆ど書かずに、年末に100冊をまとめて紹介したのみです。そう言った理由もあり、ランキングに入った本は100冊の中に含まれているのが多いです。また過去に紹介したもので検索上位に入るものは、ランク外でもロングセラーとして根強い人気でした。この結果を見ると、いかに良い本を紹介するかが決め手ですね。
 ランク内で個別の記事で紹介した本は、入門Chef Soloと銃・病原菌・鉄、金融商品にだまされるな!の3点のみです。入門Chef Soloは圧倒的な人気で、昨年のChefブームに上手く乗れたと思います。またそもそも、この入門Chef Solo自体がChefブームの火付け役になったことは間違いないでしょう。「銃・病原菌・鉄」は、私の最も好きな本の1冊です。Kindle化もされたこともあり、手に入れやすく読みやすくなりました。そのこともあり、何回も紹介しています。「金融商品にだまされるな!」は、仕組預金のエントリーで紹介しています。仕組預金とは何ぞやと知りたくて検索されるようです。実際私も、この本を読んで仕組預金の仕組みが理解できました。面白いところで、「トヨタ生産方式」があります。この本、確かTweetでしか紹介していません。Retweetされて、ランクインという珍しい形態です。
 

順位 書影 比率 紹介記事
1 入門Chef Solo - Infrastructure as Code 6,94% 手動でサーバの設定をすることを禁ずる。入門Chef Solo
2 銃・病原菌・鉄 上巻 2.82% 今年一番面白かった本。銃・病原菌・鉄 ―1万3000年にわたる人類史の謎
3 Spidering hacks―ウェブ情報ラクラク取得テクニック101選 1.31% オープンソースのRubyのWebクローラー"Anemone"を使ってみる
4 この世でいちばん大事な「カネ」の話 1.31% 今まで読んで良かった本 100冊
5 いかにして問題をとくか 1.11% 今まで読んで良かった本 100冊
6 新装版 企業参謀 (戦略的思考とは何か) 1.01% 今まで読んで良かった本 100冊
7 ザ・ゴール 1.01% 今まで読んで良かった本 100冊
8 トヨタ生産方式―脱規模の経営をめざして 1.01% Tweet
9 金融商品にだまされるな! 1.01% これはひどい。「円仕組預金」の仕組みの裏側
10 ヤバい経営学―世界のビジネスで行われている不都合な真実 0.91% 今まで読んで良かった本 100冊


まとめ



 売上全体をみると、書籍も上位10冊で全体の18.5%を占めます。ブログ記事の閲覧とほぼ同じ比率で、ロングテールのヘッドとなっています。全く意図せずそうなっているのが、面白いところです。ブログを書き出して今年で10年目です。そこまで続けていると、自分のブログで統計的なことがある程度解るようになりました。そして、振り返りを行うことにより、新たな気付きが出てきます。反響があって、非常にありがたいかぎりです。
 ブログを書く上で、私にとって本の紹介は非常に難しい分野の1つです。まだまだ勉強の余地があるので、今年は意識して紹介の仕方を工夫してみるつもりです。(それ以前に、本の紹介エントリーを書かないといけませんね)


See Also:
2011年、Amazonアソシエイト結果 書籍編
2010年、Amazonアソシエイト結果
2009年、Amazonアソシエイト結果
2013年の日記の振り返り
今まで読んで良かった本 100冊

2013年の日記の振り返り

 2014年になったことで、恒例の日記振り返りです。(4回目です。しかし去年は忘れてました)
トータルアクセスは、674,188件。2012年が448,369件だったので、約1.5倍です。2011⇒2012年が1.76倍だったので、伸び率としては低下しています。一方で、単純な数字で比較すると、伸びているので良しとします。


 2013年に書いたエントリー数は134件で、2012年の119件に較べて1割増です。アクセスの伸びの要因としては、何と言ってもはてなブックマークのアルゴリズムの変更です。新アルゴリズムへの変更で、ホットエントリーに簡単に載るようになりました。一度ホットエントリーに載ると最低でも1,000アクセスぐらいは見込めるので、アクセス数の底上げに繋がりました。新アルゴリズムについては、賛否色々あったようですが、アクセス数を増やし広告収入を増やすというはてなの運営側の狙いとしては当たっているのではないでしょうか。
 Google Analysticsでアクセスの流入元を見てみると、1位は検索経由で20.48%。2位がソーシャルで10.87%です。このソーシャルの中に、はてなブックマークも含まれています。3位がリファラーということで、他のサイトからのリンクが9.75%です。このリファラーには、Gunosyやfeedly、そしてはてなの本体サイトが含まれています。つまりは2位と3位がソーシャルということで、20%くらいで検索経由とほぼ同じだけ来ている模様です。この部分が純増分の大きな要因と推測されます。

2013年の人気エントリー



 2013年の人気エントリーは以下の通りです。我ながら衝撃を受けるのですが、1〜3位までワイン関係のエントリーです。そして、4位が掃除機のエントリーです。プログラマ系のエントリーを心掛けているのですが、どうやら世間が私に求めていることは違うようです。まぁIT系と生活系のエントリーでは、読む人の母数が違うので気にせず生きていくことにします。

順位 タイトル 掲載日 ブックマーク数 いいねの数 比率
1 私が旨いと思う、普段飲みの1,000円台のワイン 2013年9月30日 356 3.58%
2 身も蓋も無い1,000円台のワインの選び方 2013年9月30日 99 2.87%
3 ワインの品種。まずは3つだけ覚えておけば大丈夫 2013年10月13日 107 2.77%
4 掃除機は、ダイソンよりルンバさんより、マキタの充電式クリーナー 2013年11月10日 182 2.53%
5 今まで読んで良かった本 100冊 2013年12月25日 24 1.97%
6 メモリー増設の参考に!!Dellのモデル別、最大搭載メモリー一覧 2012年6月5日 4 1.97%
7 家庭内ストレージ/NASのあれこれ。保存方法からバックアップ対象まで 2013年9月1日 26 1.90%
8 4,000円でMacbookのバッテリーを交換するの話。或いはMacbookの交換バッテリー一覧 2012年6月22日 6 1.41%
9 自分を首に出来るように働く 2013年12月24日 40 0.77%
10 Macbook Pro RetinaのApple 85W MagSafe 2電源アダプタが燃えた件。 2013年5月15日 81 0.71%

まとめ



 このブログは、基本的に私自身の備忘録です。何かやる時は、メモを残して置かないとすぐに忘れます。ブログに残すことで頭の中の整理にもなりますし、閲覧して頂いた人からのフィードバックもあり、いい事ばかりです。忙しい時は、ついつい面倒くさくなって更新が滞りますが、例えメモでも良いので残すように心掛けていきます。
 それでは、今年もよろしくお願い致します。


See Also:
2009年の日記振り返り
2010年の日記振り返り
2011年の日記振り返り

仕事を分解する。


 昔上司が言った中で、印象に残っている言葉があります。部員に対するフィードバックで、全員に5分づつ個別に面談をする必要があったそうです。30人×5分で150分と3時間弱の時間が掛かると計算です。3時間とまとまった時間はなかなか取れないので、紙の束を見てやらないと思っていたそうです。
 しかし、暫くして気がついたそうです。毎日10〜15分であれば確実に時間は空いているし、その時間があれば2〜3人と面談が出来るということに。仕事を全体の総量で考えると大変で中々取り組めないが、分解すると1つ1つはたいしたことが無いということですね。新人の頃だったので、なる程と思っていました。


 アジャイルの手法の1つに、スクラムがあります。スクラムではストーリというユーザの要求に優先順位をつけて、タスクに落としこんでいきます。タスクについては、実施段階ではもっと細分化してチケットなどで管理することが多いです。一つ一つのタスクを扱い易い粒度に分解しチケットで管理することは、よくよく考えると冒頭の考え方と同じですね。


 もちろん全ての仕事が分解出来る訳ではありません。じっくり考える必要がある仕事は、細切りの時間よりまとまった時間で集中してやる方が効率が良いです。しかし、分解することで効率よく出来る仕事もあります。その辺りを見極めて、取り組めると良いですね。


See Also:
自分を首に出来るように働く
技術を伝えても、技術者の価値はなくならないという話
5分くらいで出来るやる気の出し方