用意するのは
あくまでサンプルですので、CSSセレクタも使えなければ最新のWebScraperの様に相対/絶対URL展開や、フィルタ等はサポートしていません。
またresultも動作させていない為、結果が全て戻ります。
さらにltxmlが内部で使っているTinyXML/TinyXPathの仕様からか、XPathの途中に「//」をめり込ます事が出来ませんでした。
まずLua版WebScraperのソース。
luascraper.lua
local http = require("socket.http")
local xml = require("xml")
-- return process structure
function process(t)
return {name="process",process={xpath=t[1], name=t[2], scraper=t[3]}}
end
-- not supported
function result(p)
return p
end
-- return scraper structure
function scraper(self)
self.name = "scraper"
-- scrape method
function self.scrape(url, ctx)
-- create http session and parse HTML
if ctx == nil then
local chunk = {}
local b, c = http.request {
method = "GET",
url = url,
sink = ltn12.sink.table(chunk)
}
if not c == 200 then
return nil
end
local html = table.concat(chunk)
ctx = {op = self, doc = xml.parse(html)}
end
-- scraping...
self.res = {}
if not ctx.doc then
return nil
end
for k,v in pairs(self) do
if (type(v) == "table" and v.name == "process") then
if (type(v.process.scraper) == "table") then
for k1,v1 in pairs(ctx.doc:select(v.process.xpath)) do
local newctx = {top=ctx.top, doc=v1}
self.res[#(self.res)+1] = v.process.scraper.scrape(url, newctx)
end
else
local node = ctx.doc:select(v.process.xpath)
if node then
local attr = v.process.scraper
if attr == "TEXT" then
self.res[v.process.name] = node[1]:text()
elseif string.sub(attr, 1, 1) == "@" then
attr = string.sub(attr, 2)
self.res[v.process.name] = node[1]:attribute(attr)
end
end
end
end
end
return self.res
end
return self
end
案外ボリューム無く書けました。このモジュールを使って私のtwitter/with_friendsの発言リストをスクレイピングするLuaスクリプトがコレ
twitter_scraper.lua
require "luascraper"
local s = scraper {
process {'//tr[@class="hentry"]',
'status', scraper {
process {'//td[@class="content"]/strong/a', 'nick', 'TEXT'},
process {'//td[contains(@class,"author")]/a/img', 'name', '@alt'},
process {'//td[contains(@class,"author")]/a/img', 'image', '@src'},
process {'//span[contains(@class,"entry-title")]', 'description', 'TEXT'},
process {'//a[@rel="bookmark"]', 'url', '@href'},
}},
result = 'friends';
}
function dump(r)
print('-')
for k,v in pairs(r) do
if type(v) == "table" then
dump(v)
else
print(k,v)
end
end
end
r = s.scrape('http://twitter.com/mattn_jp/with_friends/')
dump(r)
そして結果がコレ
image http://s3.amazonaws.com/twitter_production/profile_images/24072332/negipo_normal.png
name Yoshiteru Negishi
url http://twitter.com/negipo/statuses/371889282
description fooo.nameのおかげで自分が入り忘れてるウェブサービスがわかるようになった
nick negipo
-
image http://s3.amazonaws.com/twitter_production/profile_images/34076402/crestock-221345-1024x768_normal.jpg
name ハラヘ(´・ω・`)
url http://twitter.com/mobcov/statuses/371888702
description 今見るとシローアマダはかっこ悪いけどアイナサハリンは(ry
nick mobcov
-
image http://s3.amazonaws.com/twitter_production/profile_images/33598712/wt_normal.png
name 暴君
url http://twitter.com/VoQn/statuses/371888452
description 授業終わった。やっとご飯食べられる
nick VoQn
-
image http://s3.amazonaws.com/twitter_production/profile_images/24072332/negipo_normal.png
name Yoshiteru Negishi
url http://twitter.com/negipo/statuses/371887582
description はてなperlグループに入った
nick negipo
-
image http://s3.amazonaws.com/twitter_production/profile_images/34078402/cat_888_normal.gif
name (c)yabkoji
url http://twitter.com/yabkoji/statuses/371887022
description 激スイマー襲来中。
nick yabkoji
-
image http://s3.amazonaws.com/twitter_production/profile_images/22560082/nobita_normal.jpg
name kimidora
url http://twitter.com/kimidora/statuses/371886072
description ねむいねむいねむいねむいねむいねむいねむいねむいねむいねむい。。。。。。。。。。ぐぅ *Tw*
nick kimidora
-
image http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name highness
url http://twitter.com/smokeymonkey/statuses/371885732
description うぅ、ムラサメで部長とカブった。
nick smokeymonkey
-
image http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name highness
url http://twitter.com/smokeymonkey/statuses/371885022
description はてなグループって排他制御あるのかしら。
nick smokeymonkey
-
image http://s3.amazonaws.com/twitter_production/profile_images/34076402/crestock-221345-1024x768_normal.jpg
name ハラヘ(´・ω・`)
url http://twitter.com/mobcov/statuses/371884382
description TextMateアップデートキターーーーー!!
nick mobcov
-
image http://s3.amazonaws.com/twitter_production/profile_images/32257122/basara_normal.jpg
name japo
url http://twitter.com/japo/statuses/371884052
description ハマーン様万歳だろJK
nick japo
-
image http://s3.amazonaws.com/twitter_production/profile_images/19383642/ore_normal.jpg
name Sugano Yoshihisa(E)
url http://twitter.com/koshian/statuses/371883862
description 「あのPerlモジュールなんてったっけ?」とぐぐったら、自分のはてなブックマークがひっかかって見事に発見
nick koshian
-
image http://s3.amazonaws.com/twitter_production/profile_images/22022432/plagger_logo_purple_normal.png
name plagger.org
url http://twitter.com/plagger/statuses/371883772
description Safariの『Webクリップ』を試してみる。 - sta la sta
nick plagger
-
image http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name highness
url http://twitter.com/smokeymonkey/statuses/371882682
description うわ、 GFF でペーネロペー出てるのか。超欲しい。
nick smokeymonkey
-
image http://s3.amazonaws.com/twitter_production/profile_images/33078022/icon_normal.gif
name Miki@7500
url http://twitter.com/7500/statuses/371881092
description 午後の部にとりかかりまっしゅ!夕方までしゃいなら?ノシ
nick 7500
-
image http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name highness
url http://twitter.com/smokeymonkey/statuses/371879692
description 初代からν→ F91 まで + アレックスと 08 小隊とデンドロビウムは把握してる。その後はさっぱりだな。
nick smokeymonkey
-
image http://s3.amazonaws.com/twitter_production/profile_images/15059862/al3x_normal.jpg
name Alex Payne
url http://twitter.com/al3x/statuses/371879502
description Oh, how I wanted to be rid of MacPorts. Curse you, Image/Rmagick.
nick al3x
-
image http://s3.amazonaws.com/twitter_production/profile_images/34297902/kamon_normal.png
name wrongbee
url http://twitter.com/wrongbee/statuses/371878872
description ペーネロペーの画像検索結果
nick wrongbee
-
image http://s3.amazonaws.com/twitter_production/profile_images/33078022/icon_normal.gif
name Miki@7500
url http://twitter.com/7500/statuses/371878362
description @
nick 7500
-
image http://s3.amazonaws.com/twitter_production/profile_images/15927972/otsune_hanaji_purple_normal.jpg
name ??uns?o ??n??s??
url http://twitter.com/otsune/statuses/371877452
description Pukkaのすばらしい所はdel.icio.usのアカウント切り替えが一瞬でプルダウンメニューで選べる所だ。bookmarkletなんかでソーシャルブックマークしてたらログアウト・ログインの時間分だけ人生を無駄にする lang:ja
nick otsune
-
image http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name highness
url http://twitter.com/smokeymonkey/statuses/371876992
description 閃光のハサウェイはガンダムサイドストーリーでは一番好きだ。
nick smokeymonkey
-
-
Luaでもやれない事はない!追記
result処理、相対/絶対URL展開処理を加えて、CodeReposに入れておきました。