scRUBYt! は Web Spidering & Scraping ツールです。スクリプト言語 Ruby のライブラリです。 Web ページを取得/変換し、情報を取り出すツールの作成に使用します。ライセンスは GPL v2 です。
ここでは、 Windows におけるインストールの注意点、パッチ、トラブル、実例(の示唆)を提供します。使用した scRUBYt! のバージョンは 0.3.4 です。
詳細な解説はありません。経験の提供を目的としています。
scRUBYt! の概略は google で検索するか、 @IT の記事「進化する“Webスクレイピング”技術の世界」を参照してください。
簡単に説明すると、 html から XPath で参照点を指定しデータを取り出すライブラリです。 developerWorks の古い記事「Webベースのデータ・マイニング」をご存知の方は想像しやすいかもしれません。
以下、説明で使用する %RUBY_HOME% は Ruby バイナリをインストールしたディレクトリです。
gem でインストールします。
本家の解説はこちら。
Installation Instructions - Scrubyt
http://wiki.scrubyt.org/index.php?title=Installati...
バージョンは現時点(2008/11/13thu)で動作している環境です。後述するパッチをあてています。
- Ruby バイナリ
- ActiveScriptRuby 1.8.7 (2008-08-11 patchlevel 72)
- Ruby 拡張開発ライブラリ
- asr に同梱
-
Ruby をビルドしたコンパイル環境 - scRUBYt! 0.3.4
- 依存ライブラリ( gem を使う場合は自動でインストールされます。依存ライブラリの依存ライブラリは明記してません)
- hpricot 0.6.164-x86-mswin32
- mechanize 0.8.4
- ParseTree 3.0.2
- ParseTreeReloaded 0.0.1
- RubyInlineAcceleration 0.0.1
- ruby2ruby 1.2.1
- RubyInline 3.8.1
scRUBYt! が依存するライブラリ ParseTree が RubyInline に依存し、これが C コンパイラを要求します。 Windows 版 Ruby は rbconfig.rb などの制約から、 Ruby のビルドに使用した環境でなければ拡張ライブラリを作成できません。 ActiveScriptRuby 向けの拡張ライブラリを作成する場合は vc6 環境を用意してください。 vc6 などの商用もしくは古い環境を用意できない場合は、フリー開発環境でビルドされた Ruby バイナリを用意し、フリー開発環境をセットアップしてください。異なる開発環境でも rbconfig.rb を書き換え *.lib を再作成すれば誤魔化せるかもしれませんが(僕は ActiveScriptRuby でやりました)、
なお、 ParseTree の so ファイルが作成されたあとは、コンパイラは不要です。 %INLINEDIR% ディレクトリに作成された so ファイルをコピーすれば、コンパイラのない環境でも scRUBYt! を利用できます(todo 再確認)。
ParseTree 3.x.x 以降、 gem install で Windows 用にビルドされたパッケージがインストールされるようになりました。現在は scRUBYt! を使用する範囲ではコンパイル環境は不要です。以下に説明する設定も(おそらく)不要です。
scRUBYt! 0.3.4 は RubyInline のバージョン 3.6.3 を要求するのですが、
gem install -f scrubyt
Ruby の gem ライブラリ ディレクトリ %RUBY_HOME%/lib/ruby/gems/1.8/gems に潜って、依存ライブラリにユニットテストが用意さているか確認してください。 test ディレクトリがあれば、その下のテスト スクリプトを実行し、テストが通ることを確認します( RubyInline のテストは %TEMP% の下にゴミを作るかもしれない。それに mkdir でトラブって動かなかったような...)。インストールと同時にテストする場合は -t オプションをつけてインストールします。
依存ライブラリ RubyInline が環境変数 INLINEDIR を参照します。環境変数 INLINEDIR はコンパイルに使用するディレクトリです。ソース、ビルドした拡張ライブラリなどが保存されます。
適当な場所(たとえば %RUBY_HOME%/lib/ruby/gems/1.8/gems/.ruby_inline )を決め、環境変数 INLINEDIR に設定します。
RubyInline が caller の処理で windows のファイル パスの構造を考慮してないため問題が発生します。
--- inline.rb.orig 2008-06-21 00:39:00 +0900 +++ inline.rb 2008-06-21 00:39:00 +0900 @@ -253,7 +253,8 @@ 0 end - file, line = caller[1].split(/:/) +# file, line = caller[1].split(/:/) + file, line = caller[1].scan(/(.+):(\d+)(?=$|:)/).first result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG and not $TESTING @src << result @@ -295,7 +296,8 @@ raise "Couldn't discover caller" if stack.empty? real_caller = stack.first real_caller = stack[3] if real_caller =~ /\(eval\)/ - real_caller = real_caller.split(/:/, 3)[0..1] +# real_caller = real_caller.split(/:/, 3)[0..1] + real_caller = real_caller.scan(/(.+):(\d+)(?=$|:)/).first @real_caller = real_caller.join ':' @rb_file = File.expand_path real_caller.first @@ -429,7 +431,7 @@ '-I', hdrdir, config_hdrdir, '-I', Config::CONFIG['includedir'], - "-L#{Config::CONFIG['libdir']}", +# "-L#{Config::CONFIG['libdir']}", '-o', so_name.inspect, File.expand_path(src_name).inspect, libs,
s.add_dependency(%q<RubyInline>, [">= 3.6.3"])
ParseTree がコンパイル オプション -Werror を付けて、これがエラーになる場合は parse_tree.rb の当該箇所をコメントアウトします。 extern もエラーになるかもしれない( ParseTree 3.0.2 では対処されている)。
--- parse_tree.rb.orig 2008-06-15 11:19:27 +0900 +++ parse_tree.rb 2008-11-08 15:25:27 +0900 @@ -288,7 +288,7 @@ # 1) Get me a login on your box so I can repro this and get it fixed. # 2) Fix it and send me the patch # 3) (quick, but dirty and bad), comment out the following line: - builder.add_compile_flags "-Werror" +# builder.add_compile_flags "-Werror" builder.prefix %{ #define nd_3rd u3.node @@ -1051,7 +1051,7 @@ } } - builder.prefix " extern NODE *ruby_eval_tree_begin; " \ + builder.prefix " RUBY_EXTERN NODE *ruby_eval_tree_begin; " \ if RUBY_VERSION < '1.9.0' builder.c %Q{
vc7tk で asr の拡張ライブラリをビルドするためのパッチです。
config.h のパッチです。
--- config.h.orig 2007-03-17 11:54:54 +0900 +++ config.h 2008-06-14 18:03:07 +0900 @@ -1,6 +1,8 @@ +/* #if _MSC_VER != 1200 #error MSC version unmatch #endif +*/ #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1
vcvars32.bat の設定例です。 config.h の変更でコンパイルできるはずですが、念のため。
rem vcvars32.bat - vc7tk rem @echo off rem call D:\EXPF\Mingw\cmd.bat set VC7TKInstallDir=D:\EXPF\Microsoft Visual C++ Toolkit 2003 set VC7TKMSVSDir=%ProgramFiles%\Microsoft Visual Studio .NET 2003\Vc7 Set PATH=%VC7TKInstallDir%\bin;%PATH% Set INCLUDE=%VC7TKInstallDir%\include;%VC7TKMSVSDir%\include;%INCLUDE% Set LIB=%VC7TKInstallDir%\lib;%VC7TKMSVSDir%\lib;%LIB% rem psdk set PSDKInstallDir=D:\EXPF\PSDK4WS2003R2 call %PSDKInstallDir%\SetEnv.Cmd /2000 %* set INCLUDE=%MSSdk%\include\mfc;%INCLUDE% set INCLUDE=%MSSdk%\include\atl;%INCLUDE% set INCLUDE=%MSSdk%\include\crt;%INCLUDE%
mingw で asr の拡張ライブラリをビルドするためのパッチです。 RubyInline の実行に必要な程度の変更です。 rbconfig.rb は hpricot に付属する extras/mingw-rbconfig.rb を使うほうが簡単かもしれない...(未確認)
vc7tk と同じく config.h を変更します。
RubInline の inline.rb の当該行をコメントアウトします。
" -link /LIBPATH:\"#{Config::CONFIG['libdir']}\" /DEFAULTLIB:\"#{Config::CONFIG['LIBRUBY']}\" /INCREMENTAL:no /EXPORT:Init_#{module_name}" when /mingw32/ then
rbconfig.rb のパッチです。
--- rbconfig.rb.orig 2008-05-15 16:17:22 +0900 +++ rbconfig.rb 2008-06-22 12:57:45 +0900 @@ -22,12 +22,12 @@ CONFIG["SHELL"] = "$(COMSPEC)" CONFIG["BUILD_FILE_SEPARATOR"] = "\\" CONFIG["PATH_SEPARATOR"] = ";" - CONFIG["CFLAGS"] = "-MD -Zi -O2b2xg- -G6" + CONFIG["CFLAGS"] = "-O2 -mtune=pentium3" CONFIG["CPPFLAGS"] = "" CONFIG["CXXFLAGS"] = "" CONFIG["FFLAGS"] = "" CONFIG["LDFLAGS"] = "" - CONFIG["LIBS"] = "oldnames.lib user32.lib advapi32.lib wsock32.lib " + CONFIG["LIBS"] = "-luser32 -ladvapi32 -lwsock32 " CONFIG["exec_prefix"] = "$(prefix)" CONFIG["bindir"] = "$(exec_prefix)/bin" CONFIG["sbindir"] = "$(exec_prefix)/sbin" @@ -56,8 +56,8 @@ CONFIG["target_cpu"] = "i386" CONFIG["target_vendor"] = "pc" CONFIG["target_os"] = "mswin32" - CONFIG["CC"] = "cl -nologo" - CONFIG["CPP"] = "cl -nologo -E" + CONFIG["CC"] = "gcc" + CONFIG["CPP"] = "gcc -E" CONFIG["YACC"] = "byacc" CONFIG["RANLIB"] = "" CONFIG["AR"] = "lib -nologo" @@ -67,14 +67,14 @@ CONFIG["CP"] = "copy > nul" CONFIG["ALLOCA"] = "" CONFIG["DEFAULT_KCODE"] = "" - CONFIG["OBJEXT"] = "obj" + CONFIG["OBJEXT"] = "o" CONFIG["XCFLAGS"] = "-DRUBY_EXPORT -I. -I./.. -I./../missing" CONFIG["XLDFLAGS"] = "-stack:0x2000000" CONFIG["DLDFLAGS"] = "-link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) -implib:$(*F:.so=)-$(arch).lib -pdb:$(*F:.so=)-$(arch).pdb" CONFIG["ARCH_FLAG"] = "" CONFIG["STATIC"] = "" CONFIG["CCDLFLAGS"] = "" - CONFIG["LDSHARED"] = "cl -nologo -LD" + CONFIG["LDSHARED"] = "gcc -shared" CONFIG["DLEXT"] = "so" CONFIG["DLEXT2"] = "dll" CONFIG["LIBEXT"] = "lib"
scRUBYt! 0.3.4 で開発していると様々なトラブルにあうと思います。 Scrubyt::Extractor.define のブロックで問題のある記述があると無限ループに陥ったり、 windows パスを考慮してなかったり、 $KCODE を書き換えていたり、 puts url がうるさかったり、問題があります。
下はアドホックなパッチです。 puts url は grep -r scrubyt-0.3.4 で検索してコメントアウトしてください。 $KCODE は require 'scrubyt' したあとに再設定するか grep で当該箇所を見つけてコメントアウトしてください。
diff -r -u scrubyt-0.3.4.orig/lib/scrubyt/core/scraping/filters/tree_filter.rb scrubyt-0.3.4/lib/scrubyt/core/scraping/filters/tree_filter.rb --- scrubyt-0.3.4.orig/lib/scrubyt/core/scraping/filters/tree_filter.rb 2008-06-21 00:52:39 +0900 +++ scrubyt-0.3.4/lib/scrubyt/core/scraping/filters/tree_filter.rb 2008-06-21 00:52:39 +0900 @@ -112,7 +112,7 @@ child_pattern.generalize ? XPathUtils.generate_generalized_relative_XPath(child_pattern.filters[current_example_index].temp_sink, result) : XPathUtils.generate_relative_XPath(child_pattern.filters[current_example_index].temp_sink, result) end - break if @parent_pattern.children[0].filters.size == current_example_index + 1 + break if @parent_pattern.children[0].filters.size == current_example_index + 1 || @parent_pattern.children[0].nil? current_example_index += 1 end when EXAMPLE_TYPE_IMAGE diff -r -u scrubyt-0.3.4.orig/lib/scrubyt/core/shared/extractor.rb scrubyt-0.3.4/lib/scrubyt/core/shared/extractor.rb --- scrubyt-0.3.4.orig/lib/scrubyt/core/shared/extractor.rb 2008-06-21 00:52:39 +0900 +++ scrubyt-0.3.4/lib/scrubyt/core/shared/extractor.rb 2008-06-21 00:52:39 +0900 @@ -33,7 +33,7 @@ @processed_pages = [] backtrace = SharedUtils.get_backtrace - parts = backtrace[1].split(':') + parts = backtrace[1].scan(/(.+):(\d+)(?=$|:)/).first source_file = parts[0] Scrubyt.log :MODE, mode == :production ? 'Production' : 'Learning'
実行するには次の3つのファイルをどこかから入手し、下記スクリプトと同じディレクトリに保存します。ヒントはありません。ファイル名は参考になりません。ちょっとアレかもしれないので伏せます(スクリプトを読めば想像つくと思いますが...)。
- spl.htm
- uni.htm
- adj.htm
#!ruby -Ks require 'rubygems' require 'scrubyt' # scrubyt.rb が $KCODE = 'u' してるので再設定する。 $KCODE = "s" class CorporateActionSplit def self.parse( iPath ) Scrubyt::Extractor.define do #Perform the action(s) fetch( iPath ) #Construct the wrapper title( '//div[@class="title-text"]' ) lastmodified( '//table[@width="550"][@cellspacing="0"][@cellpadding="1"]/' + 'tr[1]/td[@class="mtext"][@align="right"]' ) header( '//table[@width="550"][@cellspacing="1"][@cellpadding="1"]/' + 'tr[1]' ) do name( '/td[@class="mtext-db">]' ) end row( '//table[@width="550"]/tr[@*]' ) do date( '/td[@class="mtext"][@bgcolor="#ffffff"][1]' ) brand( '/td[@class="mtext"][@bgcolor="#ffffff"][2]' ) market( '/td[@class="mtext"][@bgcolor="#ffffff"][3]' ) size( '/td[@class="mtext"][@bgcolor="#ffffff"][4]' ) end end end def self.scraping( iPath, iClass = CorporateActionSplit ) # todo result = iClass.parse( iPath ) puts result.to_xml end end # class CorporateActionSplit class CorporateActionAdjust def self.parse( iPath ) Scrubyt::Extractor.define do #Perform the action(s) fetch( iPath ) #Construct the wrapper title( '//div[@class="title-text"]' ) lastmodified( '//table[@width="550"][@cellspacing="0"][@cellpadding="1"]/' + 'tr[1]/td[@class="mtext"][@align="right"]' ) header( '//table[@width="550"][@cellspacing="1"][@cellpadding="1"]/' + 'tr[1]' ) do name( '/td[@class="mtext-db">]' ) end row( '//table[@width="550"]/tr[@*]' ) do date( '/td[@class="mtext"][@bgcolor="#ffffff"][1]' ) brand( '/td[@class="mtext"][@bgcolor="#ffffff"][2]' ) market( '/td[@class="mtext"][@bgcolor="#ffffff"][3]' ) quart( '/td[@class="mtext"][@bgcolor="#ffffff"][4]' ) prev( '/td[@class="mtext"][@bgcolor="#ffffff"][5]' ) curr( '/td[@class="mtext"][@bgcolor="#ffffff"][6]' ) ratio( '/td[@class="mtext"][@bgcolor="#ffffff"][7]' ) end end end def self.scraping( iPath, iClass = CorporateActionAdjust ) # todo result = iClass.parse( iPath ) puts result.to_xml end end # class CorporateActionAdjust class CorporateActionUnit def self.parse( iPath ) Scrubyt::Extractor.define do #Perform the action(s) fetch( iPath ) #Construct the wrapper title( '//div[@class="title-text"]' ) lastmodified( '//table[@width="550"][@cellspacing="0"][@cellpadding="1"]/' + 'tr[1]/td[@class="mtext"][@align="right"]' ) header( '//table[@width="550"][@cellspacing="1"][@cellpadding="1"]/' + 'tr[1]' ) do name( '/td[@class="mtext-db">]' ) end row( '//table[@width="550"]/tr[@*]' ) do date( '/td[@class="mtext"][@bgcolor="#ffffff"][1]' ) brand( '/td[@class="mtext"][@bgcolor="#ffffff"][2]' ) market( '/td[@class="mtext"][@bgcolor="#ffffff"][3]' ) prev( '/td[@class="mtext"][@bgcolor="#ffffff"][4]' ) curr( '/td[@class="mtext"][@bgcolor="#ffffff"][5]' ) end end end def self.scraping( iPath, iClass = CorporateActionUnit ) # todo result = iClass.parse( iPath ) puts result.to_xml end end # class CorporateActionUnit base = File.dirname( $0 ) path = File.join( base, "spl.htm" ) result = CorporateActionSplit.scraping( path ) path = File.join( base, "uni.htm" ) result = CorporateActionUnit.scraping( path ) path = File.join( base, "adj.htm" ) result = CorporateActionAdjust.scraping( path )
他の書き方。
class CorporateActionSplit def self.parse( iPath ) Scrubyt::Extractor.define do #Perform the action(s) fetch( iPath ) #Construct the wrapper title( '//div[@class="title-text"]' ) lastmodified( '//table[@width="550"][@cellspacing="0"][@cellpadding="1"/tr[1]/td[@class="mtext"][@align="right"]' ) row( '//table[@width="550"][@cellspacing="1"][@cellpadding="1"]/tr[@*]') do date( "分割権利落ち日" ) brand( "銘柄" ) market( "市場" ) size( "割当比率" ) end end end def self.scraping( iPath, iClass = CorporateActionSplit ) # todo end end # class CorporateActionSplit
XPath 式で、式の途中でタグを属性や配列の添字で修飾した場合に出力がおかしくなる場合は、最後に指定したタグに[@*]をつけると回避できます。
row( '//table[@width="550"]/tr[@*]' ) do
パターン指定と同時に :type => :html_subtree すると期待通りの値が得られないようです。
text( '//p', :type => :html_subtree )
ブロックで囲ってやるとうまくいく。
text( '//p' ) do html( :type => :html_subtree ) end
inner_html.gsub(/<.*?>/, "") した文字列が lambda に渡されます。ブロックの戻り値は配列で戻します。戻した配列が空の場合はノードは生成されません。
script( lambda{ |string| return array }, :type => :script )
いくつか問題があります。
- 実態参照を元に戻さない。
- 戻り値の重複が取り除かれる。
- このため select_indices した場合に値がずれる。バグ?
- 他のブロックに値を渡す場合はインスタンス変数を介して渡す。
他のブロックに値を渡すサンプル。
script( lambda{ |x| x.gsub!( / /, " " ) x.strip! @values = x.split( /\s+/m ) [] }, :type => :script ) brand( lambda{ [@values[0]] }, :type => :script ) ticker( lambda{ [@values[1]] }, :type => :script )
lambda を並べず :type => :constant で良さそうな気がするものの、定義時に1度だけ呼ばれて繰り返し呼ばれないので、期待通りになりません。
brand( @values[0], :type => :constant ) # @values[0] は空。
こう書けるとすっきりするんだけど...
script( lambda{ |x| x.gsub!( / /, " " ) x.strip! x.split( /\s+/m ) }, :type => :script ) do brand( ":0" ) ticker( ":1" ) end
Scrubyt::Extractor.define の戻り値は ScrubytResult です。 ScrubytResult は ResultNode を継承しています。 ResultNode は Array を継承しています。 scrubytResult.inspect すると入れ子になった空の配列に見えるのはこのためです。
scrubytResult の中には resultNode が入ってます。
サーバに負荷を掛けないよう注意します。
- 同時接続しない
- 1ページあたりの取得間隔を空ける( sleep( 5 ) で5秒ほど空ける)
- スクリプトを再入可能にする
- 既取得分はローカルにキャッシュし、キャッシュがあればそれを利用する。
- 大量にページを取得する場合は1日あたりの実行回数を少なくする(1〜2回)
Scrubyt::Extractor.define 内でブロック名にアンダースコアから始まる名前を使用すると返り値からブロックが省略されます。
Scrubyt::Extractor.define do fetch( path ) # 戻り値に _table ブロックは含まれない。ブロックの中身は返ってくる。 _table( '//table' ) do th( "/th" ) # 下はエラーになる。 _td( "/td" ) end end
行儀の悪い html は、当然のことながら上手にパースできません。 HTML Tidy で xhtml に変換すれば、回避できるかもしれません。
HTML Tidy の ruby interface があります。このライブラリは tidy.dll を使用します。 tidy.dll をパスの通った場所に保存して gem install tidy してください。
RubyForge: Tidy: Project Info
http://rubyforge.org/projects/tidy
HTML Tidy Project Page
http://tidy.sourceforge.net/
Tidy Binaries
http://int64.sourceforge.net/tidy.html
#!ruby -Ks require 'tidy' Tidy.path = 'tidy.dll' # パスが通っていればこれで読み込める。 input = "<title>Foo</title><table></tr></table><p>Foo! <<b>bold</b>>" xhtml = Tidy.open( :show_warnings => true ) do |tidy| tidy.options.language = "jp" # input: shiftjis tidy.options.input_encoding = "shiftjis" # output: shiftjis, utf8, utf16, utf16be, utf16le, raw, ... tidy.options.output_encoding = "shiftjis" tidy.options.output_xhtml = true xhtml = tidy.clean( input ) puts( tidy.errors ) puts( tidy.diagnostics ) xhtml end puts xhtml
挿入する場所は、scrubyt-0.4.06 では例えば lib/scrubyt/core/scraping/pre_filter_document.rb に定義されているクラス メソッド br_to_newline が適当でしょう。このメソッドは alias できないので再定義します。 tidy_normalize を定義してこの例のコメント箇所を有効にしてください。
module Scrubyt class PreFilterDocument def self.br_to_newline(doc) # doc = tidy_normalize(doc) doc.gsub(/<br[ \/]*>/i, "\r\n") doc = doc.tr("\240"," ") end end end
open-uri を使った https 接続は、 open-uri が証明書ファイルの設定を行う機会を用意してないため、デフォルトで設定される証明書ファイルの参照パスにアクセス先の証明書が保存されてない場合は接続できません。追加できないなら、メソッドをオーバーライドして強引に書き換えます。下の例では、実行したスクリプトと同じディレクトリに site.cer の名前で保存した証明書ファイルを設定しています。
class OpenSSL::X509::Store alias :set_default_paths__hogehoge :set_default_paths def set_default_paths set_default_paths__hogehoge path = File.dirname( $0 ) path = File.join( path, "site.cer" ) self.add_file( path ) end end
証明書は ie から取り出します。 ie で対象サイトに https で接続し、ページ内の右クリック メニューからプロパティを選択、ダイアログの証明書ボタンをクリック、表示されたダイアログの証明のパス タブをクリック、証明のパス ツリーからルートを選択、証明書の表示ボタンをクリック、詳細タブをクリック、ファイルにコピー ボタンをクリック、ウイザードから Base 64 encode X.509(CER) を選択し、ファイルに保存します。
ログインは、連続してログインに失敗したり、ログイン/ログアウトを繰り返したり、おかしな行動をとった場合に、対象サイトがセキュリティの観点からユーザ id を一時凍結するなど、トラブルを招くおそれがあります。ログイン状態はセッション情報で管理しているでしょうから、ブラウザからクッキーを取り出し、スクリプトに与えることで、これを避けます。
ie の場合は下のスクリプトを使用し、クリップボードにクッキーをコピーします。
<html> <head> <meta http-equiv="Content-type" content="text/html; charset=Shift_JIS"> <!-- 京都 --> </head> <script language="JavaScript"> var obj = external.menuArguments; var doc = obj.document; var ck = doc.cookie; alert( "cookie is \"" + ck + "\". copy to clipboard." ); var cb = doc.parentWindow.clipboardData; cb.setData( "text", ck ); </script> </html>
ie への登録は「ちょこっと 強制削除」の installer.vb を借用して登録します。
ちょこっと 強制削除 - クロノス・クラウン -
http://crocro.com/pc/soft/c_del/index.html
上記スクリプトを保存したディレクトリに installer.vb をコピーし、次の箇所を書き換えます。
strTitle1 = "ちょこっと 強制削除" strFile1 = "c_del.html"
installer.vb を実行する前に、念のため全ての ie を閉じておきます。 installer.vb を実行します。 ie を再起動し、右クリックメニューに strTitle1 で指定した名前のメニューが追加されていることを確認します。
クリップボードにコピーしたクッキーは、スクリプトのオプションに指定してスクリプトに与えます。オプションに与えたあとは、クリップボードの内容を置き換えます。
スクレイピングが終わったらログアウトします。必ずログアウトしてください。
セッション情報の漏洩はセキュリティ上問題があります。取り扱いには充分注意し、スクレイピング後は必ずログアウトして、セッション情報を無効にしてください。
- [Ruby]HTTPSでサーバーに接続 - うなの日記 ( http://d.hatena.ne.jp/unageanu/20070504 )
- windows 環境で ruby から https に接続する方法と証明書ファイルの取得方法を紹介されてます。
- hpricot 0.6.161 は extern 関係で拡張ファイルがビルドできないかもしれない。ビルドできてもテストが通らない。
- RubyInline 3.8.1 あたりから Inline::C の内部構造が変わってしまって、 RubyInlineAcceleration 0.0.1 が動かなくなっている。 @@type_map が TYPE_MAP に変更されているため...かも。
- @@type_map = TYPE_MAP で動いてるっぽい。
- 2008/12/11 に 0.4.06 が公開された。 firewatir が必須になっている( readme では Mechanize (or FireWatir) とうたっている。 gemspec には依存関係が記述されてない。が本体で require 'firewatir' している)。
これは watir を使う。 firewatir が require 'watir/matches' しているがこのファイルは watir 1.6.2 に存在しない。 watir は windows-api 等を読み込んでいる。 windows 以外で使えるのだろうか?。- watir の一部を commonwatir に分割していたらしい。今(2009/1/23fri)は動いている。何が悪かったのだろう。
- firewatir を入れる場合は gem install firewatir する。 scRUBYt! のインストールでは自動で入らない。
- firewatir を入れたくない場合は scrubyt.rb の require "〜/agents/firewatir.rb" 行をコメントアウトする。
Ruby 1.8.7-p160 + scRUBYt! 0.4.06 + hpricot-0.8.1-x86-mswin32 な環境で次のようなエラーが出る。
NoMethodError: undefined method `each' for nil:NilClass D:/ASR/lib/ruby/gems/1.8/gems/scrubyt-0.4.06/lib/scrubyt/utils/shared_utils.rb:42:in `traverse_for_match'
lib/scrubyt/utils/shared_utils.rb のバグらしい。この修正で手元のスクリプトのユニットテストが通るようになった。
Can't get scrubyt to work - scrubyt | Google Groups
http://groups.google.com/group/scrubyt/browse_thre...
From: michael <...@gmail.com> Date: Sun, 26 Apr 2009 16:20:25 -0700 (PDT) Subject: Re: Can't get scrubyt to work You may be affected by a bug in shared_utils.rb try updating that file using: http://github.com/scrubber/scrubyt/commit/c97595d2...
Commit c97595d2ff108f801f0296b376c20d3fd67b7585 to scrubber's scrubyt - GitHub
http://github.com/scrubber/scrubyt/commit/c97595d2...
@@ -39,7 +39,7 @@ module Scrubyt results << node results.delete node.parent if node.is_a? Hpricot::Elem end - node.children.each { |child| traverse_for_match_inner.call(child, regexp) if (child.is_a? Hpricot::Elem) } + node.children.each { |child| traverse_for_match_inner.call(child, regexp) if (child.is_a? Hpricot::Elem) } if ! node.children.nil? } traverse_for_match_inner.call(node,regexp) results
- scRUBYt! - a Simple to Learn and Use, yet Powerful Web Scraping Toolkit Written in Ruby ( http://scrubyt.org/ )
- 総本山。
- RubyForge: scRUBYt!: Project Info ( http://rubyforge.org/projects/scrubyt/ )
- RubyForge にあるプロジェクト ページ。
- Reference - Scrubyt ( http://wiki.scrubyt.org/index.php?title=Reference )
- リファレンス マニュアル。
- Module: Scrubyt ( http://scrubyt.rubyforge.org/classes/Scrubyt.html )
- クラス ドキュメント。
- 前のコードじゃフォームに対応できない - あうっちの dmesg <http://d.hatena.ne.jp/autch/20080724>
- 文字コードを変換してからパースする方法。
2011/6/13mon _block_name do を記述。HTML Tidy に追記。
2009/5/1fri もろもろに NoMethodError を追記。
2009/1/24sat もろもろに追記。
2008/12/21sun scRUBYt! 0.4.06 が公開された。
2008/12/11thu シンタックス ハイライトを使ってみた。
2008/11/14fri 更新したライブラリで問題なく動いてるぽいので、バージョン情報を更新。
2008/11/13thu 不備を補った。リンク追記。
2008/7/1tue :script 追記。構成を見直した。
2008/6/26thu :html_subtree 追記。リンク追記。
2008/6/25wed インストール関連の記述を修正。あやしい記述を修正。
2008/6/23mon もろもろ修正&追記。
2008/6/22sun vc7tk, mingw 環境で asr バイナリの拡張ライブラリをビルドするためのパッチを記述。もろもろ修正&追記。
2008/6/21sat HTML tidy について記述。Spidering の注意点を記述。もろもろ修正。
2008/6/21sat ページ作成。
タグ
コメントをかく