04/02
Thu
2009
scRUBYt!を使ったスクレイピングの練習に複数のニュースサイトから最新ニュースを集めて
表示するサンプルアプリを作った。
scRUBYt!,REXMLとも適当なドキュメントが見つからず苦労した。
[環境]
VMware Server 2.0.0
Fedora 10
Apache 2.2.10
ruby 1.8.6
scrubyt 0.3.4
・XPath
scRUBYTt!でXPathの指定が期待通り動かず手間取った。
私がXPathをよくわかっていないことも原因だろうと思うが、
「:example_type => :xpath」をつけないとちゃんと動かない(?)との
情報もあり。(http://d.hatena.ne.jp/kasei_san/20090204/p1)
・参考ドキュメント
scRUBYt!
http://github.com/scrubber/scrubyt_examples/tree/master
→scRUBYt!のサンプル。
REXML
http://www.germane-software.com/software/rexml/docs/tutorial.html
→はじめの方にある「Accessing Elements」は参考になった。
http://pub.cozmixng.org/~kou/rexml-doc-ja/
→それっぽいClass,Methodを感で使ってみた。
・データの扱い
scRUBYt!のto_hash関数でHASHオブジェクトにして扱おうと思ったが
うまくいかなかった。入力データの構造に縛りがあるのだろうか。
to_xmlで出力し、REXMLオブジェクトに入れて扱う。
#!/usr/bin/env ruby
ENV['INLINEDIR']='/tmp/.ruby_inline' #RubyInlineのバグ(?)対策
require 'rexml/document'
require 'rubygems'
require 'scrubyt'
require 'kconv'
#Cnet
data1 = Scrubyt::Extractor.define do
fetch 'http://japan.cnet.com/'
record "//div[@class='section08 articlelist08']" do
link_title "//li/a", :write_text=>true do
link_url
end
end
end
xml1 = REXML::Document.new data1.to_xml
#ITPro
data2 = Scrubyt::Extractor.define do
fetch 'http://itpro.nikkeibp.co.jp/news/index.html'
record "//div[@class='newsPickup']" do
link_title "//div/span/a", :write_text=>true do
link_url
end
end
end
xml2 = REXML::Document.new data2.to_xml
#CodeZine
data3 = Scrubyt::Extractor.define do
fetch 'http://codezine.jp/'
record "//div[@id='news_list']" do
link_title "//li/a", :write_text=>true do
link_url
end
end
end
xml3 = REXML::Document.new data3.to_xml
title="News-Search | 複数のニュースサイトから最新ニュースをスクレイピング"
#以下、表示部
print <<"EOS"
Content-type: text/html; charset=shift_jis\n\n
<html>
<head>
<title>#{title}</title>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<style type="text/css">
td {border:1px black solid;vertical-align:top;}
.yellow {background-color:yellow;}
.blue {background-color:blue;}
.green {background-color:green;}
</style>
</head>
<body>
<h1>#{title}</h1>
<table style="border:1px black solid;">
<tr>
<td class="yellow">CNET</td>
<td class="blue">ITPro</td>
<td class="green">CodeZine</td>
</tr>
<tr>
<td>
EOS
xml1.elements.each("//link_title"){
|element|
puts "<a target='_blank' href=#{element.get_text('link_url')}>#{element.text}</a><br>\n"
}
print <<"EOS"
</td>
<td>
EOS
xml2.elements.each("//link_title"){
|element|
puts "<a target='_blank' href='http://itpro.nikkeibp.co.jp#{element.get_text('link_url')}'>#{element.text.tosjis}</a><br>\n"
}
print <<"EOS"
</td>
<td>
EOS
xml3.elements.each("//link_title"){
|element|
puts "<a target='_blank' href='http://codezine.jp/#{element.get_text('link_url')}'>#{element.text.tosjis}</a><br>\n"
}
print <<"EOS"
</td>
</tr>
</table>
</body>
</html>
EOS
03/30
Mon
2009
八時起床。
朝食を食べ午前中は部屋で過ごす。
昼食は国領でKと。
ドトールのコーヒーがいつの間にか200円に?前は180円だった気がする。
世田谷保険事務所に自転車で行く。結局三軒茶屋~山下間を走破。
役所の仕事って、なんというか、ストレスがすごそう。
PCの画面がCUIベースのアプリのよう(古そう)で気になった。
コーヒー 200円
駐輪場 100円
昼食 1,500円
漫画喫茶 800円
[カルディ]
コーヒー豆 500円
コーヒーフィルター 150円
ビスケット 300円
[パルケ]
サンマ(3匹) 300円
乾燥わかめ 250円
米 2500円
納豆 88円
ウィスキー 800円
03/29
Sun
2009
Apaacheがシステムの起動時に自動的に起動するように設定しようとしたら、
結構手こずったのでメモ。
[環境]
VMware Server 2.0.0
Fedora 10
Apache 2.2.10
・起動スクリプトは既にあった。
/etc/rc/init.d/httpd
---------------------------------------------------------------------------------------------
#!/bin/bash
#
# httpd Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
# description: The Apache HTTP Server is an efficient and extensible \
# server implementing the current HTTP standards.
(以下略)
---------------------------------------------------------------------------------------------
「# chkconfig: - 85 15」 が [起動レベル 起動順番 停止順番]になっている模様。
起動レベルが「-」なので起動しない。ランレベル3,5で起動するように
# chkconfig: 35 85 15 に変更
[root@VMware1 ~]# chkconfig --add httpd
[root@VMware1 ~]# chkconfig --list httpd
httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
→設定が反映されない。さっき修正した箇所が参照されているかどうかを確認するために、
# chkconfig: 35 85 16 に変更してもう一度。
[root@VMware1 ~]# chkconfig --add httpd
[root@VMware1 ~]# chkconfig --list httpd
httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@VMware1 ~]# ls -l /etc/rc3.d/*httpd
lrwxrwxrwx 1 root root 15 2009-03-29 13:23 /etc/rc3.d/K16httpd -> ../init.d/httpd
→やはり起動設定はできていないが、停止のためのシンボリックリンクは16になっているので
修正した箇所が参照はされている模様。いろいろ試したがchkconfig --addでは起動設定できなかった。
・chkconfigコマンドでレベルを指定し直接設定
[root@VMware1 ~]# chkconfig --level 35 httpd on
[root@VMware1 ~]# chkconfig --list httpd
httpd 0:off 1:off 2:off 3:on 4:off 5:on 6:off
→設定できている。
・システムをシャットダウンから起動。
[root@VMware1 ~]# service httpd status
httpd (pid 2164) を実行中...
→Apacheも起動してる。OK。rebootでも確認できた。
起動スクリプトの記述で起動設定できない理由は不明。。
VMだから?
03/28
Sat
2009
scRUBYt!のサンプルプログラムebay.rbをブラウザからアクセスして動かしてみる。
手こずったがなんとか動くようになったので作業ログ。
Webアプリにするときは表示出力部分を整えないといけない。
[環境]
VMware Server 2.0.0
Fedora 10
Apache 2.2.10
scRUBYt!-0.3.4
RubyInline-3.6.3
・とりあえずブラウザからアクセスしてみるが、500エラーになる。
Apacheのerror_logを見てみるとエラーが出力されている。
[Sat Mar 28 13:08:08 2009] [error] [client 192.168.1.2] Define INLINEDIR or HOME in your environment and try again
[Sat Mar 28 13:08:08 2009] [error] [client 192.168.1.2]
[Sat Mar 28 13:08:08 2009] [error] [client 192.168.1.2] Premature end of script headers: ebay.rb
調べてみると、「Define INLINEDIR or HOME in your environment and try again」はRubyInline-3.6.3のバグの模様。
3.6.3より上のバージョンに代えようとしたが、scRUBYt!-0.3.4はRubyInline-3.6.3が必須。scRUBYt!の0.4.1以上はfirewatirをrequireするのでパスしたい。現状の構成でエラーを解決することにする。
「Define INLINEDIR or HOME in your environment and try again」はRubyInlineが環境変数$HOME,$INLINEDIRのいずれかを参照しようとして、どちらも参照できない場合に起こる模様。(コマンドプロンプトで直接たたく際は$HOMEがあるが、Webサーバ経由で実行だとapacheユーザーになるため。)
・ebay.rbに、
ENV['INLINEDIR']=/tmp/.ruby_inline (※1)
を追記し、環境変数INLINEDIRが参照できるように修正しコマンドラインから実行。
→下記エラーが発生
[root@VMware1 goy]# /var/www/cgi-test/ebay.rb
/tmp/.ruby_inline is insecure (40777). It may not be group or world writable. Exiting.
・INLINEDIRに割り当てているフォルダのパーミッションを変更。
chmod -R 0755 /tmp/.ruby_inline
コマンドラインから実行→OK
ブラウザから実行→500エラー error_logに下記が出力される。
[Sat Mar 28 16:34:30 2009] [error] [client 192.168.1.2] /usr/lib/ruby/gems/1.8/gems/scrubyt-0.3.4/lib/scrubyt/core/scraping/filters/text_filter.rb:25: warning: don't put space before argument parentheses
[Sat Mar 28 16:34:41 2009] [error] [client 192.168.1.2] malformed header from script. Bad header=<root>: ebay.rb
・http応答ヘッダーでContent-Typeを指定するよう追記(※2)
ブラウザから実行→OK!
最終的にソースは下記のように。
--------------------------------------------------------
[root@VMware1 cgi-test]# vi ebay.rb
#!/usr/bin/ruby -K
ENV['INLINEDIR']='/tmp/.ruby_inline' # ←※1
require 'rubygems'
require 'scrubyt'
ebay_data = Scrubyt::Extractor.define do
fetch 'http://www.ebay.com/'
fill_textfield 'satitle', 'ipod'
submit
record "//table[@class='nol']" do
name "//td[@class='details']/div/a"
end
end
print "Content-type: text/html\n\n" # ←※2
puts ebay_data.to_xml
---------------------------------------------------------
~
03/28
Sat
2009
今日は朝食後、掃除洗濯。夕方までscRBYt!の研究。夜はフットサルの予定。
ガストでモーニング(朝食) 600円
セブンイレブン(昼食) 600円
夕方から買い物
駅前の東亜コーヒーでケーキセット 650円
[買い物]
りんご4つ、卵10個、レタス、きゅうり2本 1000円
食パン一斤、徳用ポークウィンナー 500円
気になる喫茶店「琥珀」に行ってみようかと思ったが、人の気配が
しなさすぎたので駅前の東亜コーヒーへ。
結構人がいる。コーヒーはうまい。best coffee of the world とのこと。
チェーン店なんだー。へー。