bar_1

contents_map

2008年3月18日火曜日

Ruby: Mechanize GUIDE.txt 日本語訳

追記2010/12/7:本内容は古くなったので、バージョン1.0.0のものに更新予定である。
追記2014-10-13: ここに最新版をおいた: http://voidptrjp.blogspot.jp/2014/10/mechanize-guide.html



http://mechanize.rubyforge.org/mechanize/ にある GUIDE.txt を訳してみた。
チュートリアルとしてよくできていると思う(原文的な意味で)。




  • ルー語っぽい箇所などを、若干修正[2008/3/31]

  • 訳微修正。SyntaxHighlighterでコード部分を整理[2010/8/5]








GUIDE.txt


Path:     GUIDE.txt
Last Update:     Tue Dec 04 19:36:28 -0800 2007







WWW::Mechanizeをはじめよう



このガイドは、Mechanize を使い始めるためのものです。このガイドを読み終わるまでに、ページをフェッチしたり、リンクをクリックしたり、フォームをうめてサブミットしたり、Webページ内から必要なデータを取り出したり、、と、お望みのいろいろな便利なことができるようになるとよいです。このガイドは、Mechanize を使ってできることの、表面的なほんとにちょっとしたスクラッチです。だけども、はじめるには十分な情報となるとよいです!

   


ページをフェッチしよう!



最初のことを最初に。mechanize を require して、新しい mechanizeオブジェクトを生成しましょう:

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new




さて、ページをフェッチするためのエージェントが使えます。グーグルをエージェントでフェッチしてみよう:

page = agent.get('http://google.com/')




なにがおこった? 我々は mechanize に対して、グーグルのメインページを取ってくるようにたのみました。Mechanize は、任意のセットされたクッキーを格納し、そしてグーグルが送ってきた任意のリダイレクトをたどりました。エージェントは、ページを我々に返しました。このページからデータを取り出したり、クリックするためのリンクを探したり、うめるためのフォームを見つけることができます。



つぎに、クリックするためのいくつかのリンクを探してみましょう。

   



リンクを見つける





Mechanize は、ページをGETしたり、POSTしたり、またはフォームをSUBMITしたとき、ページ・オブジェクトをひとつ返します。ページがフェッチされたら、エージェントはページをパースして、リンクの一覧表をページ・オブジェクト内に作ります。


それでは、グーグルのホームページをフェッチしたので、すべてのリンクを表示してみよう:

page.links.each do |link|
   puts link.text
end




リンクの一覧を表示できます。だけど、Mechanize はクリックするリンクを見つけるのに役立つ、いくつかショート・カットを用意してます。たとえば、テキストが ‘News’ であるようなリンクをクリックしたい、としましょう。ふつうは、このようにしなければなりません:

page = agent.click page.links.find { |l| l.text == 'News' }




でもMechanize には、ショートカットがあります。上記の代わりに、このようにできるのです:

page = agent.click page.links.text('News')




このショートカットは、「名前が ‘News’ であるような全てのリンクを探せ」という意味です。もしかしたら読者は「そのテキストのリンクは、複数ありうるのに!」と考えているかもしれません。そしてそれは正しい!もしクリック・メソッドに、リンクの一覧を渡した場合、Mechanize は最初のひとつをクリックします。もし二つ目のリンクをクリックしたいのなら、このようにやりましょう:

agent.click page.links.text('News')[1]




適切なリンクを以下のように探すこともできます:

page.links.href('/something')




もしくはそれらを一緒につなげて、適切なテキストと適切なhrefのリンクを探すこともできます:

page.links.text('News').href('/something')




これらのショートカットは、frame, iframe, formのようなものをフェッチしたときの任意のリストに対して、使えます。さて我々はリンクのクリックの仕方を知りました。つぎに、フォームをうめるようなもっと複雑なことをやってみましょう。

   


フォームをうめる




グーグルの例の続きをやりましょう。以下がコードです:

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new
page = agent.get('http://google.com/')




もしページが表示できれば、ひとつのfという名前のフォームがあり、2組のボタンと2,3のフィールドがあります:

pp page




いまフォームの名前がわかりましたので、ページをフェッチしてみましょう:

google_form = page.form('f')




Mechanize で、フォーム・インプット・フィールドにアクセスする方法はいくつかありますが、一番便利な方法は、オブジェクトのアクセッサを利用する方法です。では、フォーム上の ‘q’ という名前のフォーム・フィールドに、‘ruby mechanize’と入力して見ましょう:

google_form.q = 'ruby mechanize'




値をセットして、フォームを表示し、以下のような行が見えることを確認してください:

#<WWW::Mechanize::Field:0x1403488 @name="q", @value="ruby mechanize">




名前 ‘q’ に対応する値が変わっていた場合は、成功です!つぎにフォームをサブミットしてボタンを押し、結果を見てみましょう:

page = agent.submit(google_form, google_form.buttons.first)
pp page




今やったことは、検索フィールドに文字をいれて「検索」ボタンを押したのと同じことです。ボタンなしでフォームをサブミットした場合、テキスト・フィールドに入力してリターン・キーを打ったのと同じです。



コードを全部見てみましょう:

require 'rubygems'
require 'mechanize'

agent = WWW::Mechanize.new
page = agent.get('http://google.com/')
google_form = page.form('f')
google_form.q = 'ruby mechanize'
page = agent.submit(google_form)
pp page




ここまでで、スクリーン・スクレーピングをやってみました。フォームについて、もう少し深く見てみましょう。スキップしたくなる前に!

   





フォーム・テクニック応用編



このセクションでは、フォームで可能な入力フォームで違ったタイプの使用法について、触れたいと思う。パスワードやテキストエリア・フィールドは、テキスト・フィールドと同じように扱われ得る。セレクト・フィールドは、テキスト・フィールドにとても似ているが、関連するオプションがたくさんある。ひとつのオプションを選んだとき、mechanize はそれ以外のオプションを非選択にする (マルチセレクトでなければ!)




たとえばリスト上のひとつのオプションを選択しよう:

form.fields.name('list').options[0].select




今、チェック・ボックスとラジオ・ボタンを見てみよう。チェックボックスを選択するには、ただこのようにすればいい:

form.checkboxes.name('box').check




ラジオ・ボタンは、チェック・ボックスによく似ているが、同じ名前のその他のラジオ・ボタンをアンチェックする方法を知っている。チェック・ボタンと同じように、ラジオ・ボタンをチェックしてみよう:

form.radiobuttons.name('box')[1].check




Mechanize はまた、ファイルのアップロードも簡単にできる!ファイル・アップロード・フィールドを探し、ファイル名を教えてやるのだ:

  form.file_uploads.file_name = "somefile.jpg"


   



データをいじる





Mechanize は、HTMLをパースするために hpricot を使っている。これはなにを意味するか? mechanize で得たページを、hpricotオブジェクトのように扱えるということだ。 Mechanize をデータを取り出したいページのナビゲートに使った後、hpricotのメソッドで取り出せる:

agent.get('http://someurl.com/').search("//p[@class='posted']")


このパワフル・スクレーパに関するさらなる情報については、 HpricotBasics を参照してほしい。




2008年3月16日日曜日

Ruby: OptionParser (optparse.rb) の使い方

2014-05-13追記: 最新の OptionParser の網羅的機能については、「Ruby OptionParser クラスのリファレンス」 を参照してください。

OptionParser: コマンドライン・オプション解析のためのクラス

コマンドライン・オプションを解析するための方法として、従来からGNU の getopt 系のAPIが使われてきた (Getopt,GetoptLong)。Ruby ではこれらに加えて、optparse.rb の OptionParser クラスを利用する方法があるようだ。
ドキュメントは、たとえば http://stdlib.rubyonrails.org/ などに見つけることができる。
ここでこの OptionParser クラスは、従来の getopt 系クラスと使い勝手がだいぶ違うため、使いにくいという意見が散見される。実際、私も使ってみてその感があった。そこで、リファレンス・ドキュメントから主要な機能を抜き出して、使い方をまとめてみた。

OptionParserクラスの主要な機能および記述の方法

OptionParser は、コマンドラインの配列 ARGV を与えられると、その配列を解析しオプションのタイプに応じた処理を行う。ここで、「オプションのタイプに応じた処理」とは、実際には実装者が作りこむものである。
具体的には以下の3点を記述することになる:
  • オプションの定義
  • 定義されたオプションを指定したときの処理の定義
  • ヘルプ・メッセージの定義
以下にサンプルコードを示す。
#! /usr/bin/ruby
#filename: test-optparse.rb
#author: http://voidptr.seesaa.net
#date: Mar. 11th, 2008
#desc:
#ref.: http://stdlib.rubyonrails.org
#
####
require 'optparse';
require 'ostruct';
require 'pp';
#### Option Parse Method.
def option_parse( args )
#Prepare.
ost         = OpenStruct.new;
#default option values.
#
#
ost.help    = "";
ost.file    = "";
ost.kind    = "";
ost.logfile = "test.log";
ost.verbose = false;
ost.arr     = [];
#
op = OptionParser.new do |opars|
opars.banner = "NAME "+" #{$0} [options]";
opars.separator "";
opars.separator "";
#display -h description at tail of the help message.
#
#
#on_headだと、help表示のとき他のオプションとの間に改行される。
#お好みで。
#opars.on_head( "--version", "show the version." ) do
opars.on( "--version", "show the version." ) do
puts "green 1.0.0";
exit 1;
end
#オペランドありオプション(基本形; オペランドFILEは、必須)
#
#
opars.on( "-f FILE", "specify a file" ) do |f|
ost.file = f;
end
#オペランドありオプション(基本形+; オペランドKINDは必須で、値は選択式・短縮形も可)
#-k a で、-k afterと同じ。-k b で、-k before と同じ意味。
#
#
opars.on( "-k KIND", [:before, :after], "select a kind {before, after}" ) do |k|
ost.kind = k;
end
#オペランドありオプション(基本形++; オペランドは、省略可)
#
#
#
opars.on( "-l [LOGFILE]", "specify the logfile." ) do |l|
if ( l != nil ) then
ost.logfile = l;
end
end
#フラグタイプのオプション (オプションは長い形式もあり; offの形式も同時に定義)
#
#
opars.on( "-v", "--[no-]verbose", "verbose mode switch." ) do |v|
ost.verbose = v;
end
#フラグタイプのオプション
#  on_tail で、オプション定義の〆
#
opars.on_tail( "-t", "--tasukete", "show this message." ) do
puts opars;
exit 1;
end
end  #endof do |opars|.
####
#オプションなしの場合.
#
#
if ( args == [] ) then
#ヘルプを表示。
puts op;
exit 1;
end
#
op.parse!( args );
#必須オプションのチェック
#
#
if ( ost.file == "" ) then
e = OptionParser::ParseError.new;
e.reason = "file was NOT specified (#{ost.file}).";
throw e;
exit 1;
end
#
ost;
end  #endof option_parse
#### Do.
options = option_parse(ARGV)
#### Result.
pp ARGV;
puts "";
pp "Dumper #{options}"
puts "name: #{$0}";
####endof filename: test-optparse.rb

コードについて

OptionParser を newする際に、コード・ブロックを渡している。このコード・ブロック内でオプションの定義、処理、ヘルプメッセージの定義を記述する。
これら3要素は、このコード・ブロック内にすべてまとめて記述することになる —-つまり、ロジックとデータは煮込みすぎたスープのようにどろどろに熔けてしまっている。これは、OptionParserの特徴だ。
一般的には、このようなかたちはプログラミング・ポリシーとしてもオブジェクト指向的にもよろしからざることと思われる。グット・デザイン教会からは破門されるかもしれない。
ただ、ことコマンドライン・オプション処理に限っていえば、この方式はとても楽なのだ; 各オプションとそれらの説明を、一元管理できる。

2008年3月11日火曜日

g++: GNU C++ ライブラリ パート V (目次)

パート V. 文字列Strings

Table of Contents

13. 文字列クラスString Classes

シンプルな変換Simple Transformations
ケース・センシティビティCase Sensivitity
任意の文字型Arbitrary Character Types
トークン化Tokenizing
縮めてフィットShrink to Fit
CString (MFC)

g++: GNU C++ ライブラリ パート II チャプター 4. 型

チャプター 4. 型

Table of Contents

基本型Fundamental Types
数値的プロパティNumeric Properties
NULL

基本型Fundamental Types

C++は、下記の組込み型を持ちます:

  • char
  • signed char
  • unsigned char
  • signed short
  • signed int
  • signed long
  • unsigned short
  • unsigned int
  • unsigned long
  • bool
  • wchar_t
  • float
  • double
  • long double

これらの基本型は、ヘッダファイルのインクルードなしでいつでも使用可能です。これらの型は、C++またはCでまったく同じです。

これらの型のライブラリの部分を特定することは、禁止されます:その代わりPODを使います。

g++: GNU C++ ライブラリ パートI チャプター 2. セットアップ

とちゅう

2008年3月5日水曜日

xyzzy: 空白・空行無視した比較のための設定

初期設定ファイル:$XYZZY_HOME/.xyzzy に、下記を追加すればよいよ。

(setq ed::*diff-command-option* "-aBw")

※diffコマンドは、Cygwinのやつを使ってます。