読者です 読者をやめる 読者になる 読者になる

Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

世界の現在時刻をNokogiriを使って把握する

ruby xpath

仕事柄、海外との取引が多いので先方の時間が知りたくなるケースが多々有ります。
今回は、Ruby製の優秀なパーサーNokogiriと世界の時間を調べるWEBサイトTimeAndDateを併用してアレコレしてみようと思います。

とりあえず実験として

$ curl http://www.timeanddate.com/worldclock/?sort=1 > top.html

てな感じでローカルにファイルを置きつつ実験します。

ファイルを目grepすると、最初のtr以降に目当てのデータが格納されてるらしいので

require 'nokogiri'

fp = File.open("./top.html")
doc = Nokogiri::HTML.parse(fp)
doc.xpath("//table//tr[@class='c0']")

とやると

#<Nokogiri::XML::Element:0x3ff14c5333ec name="tr" attributes=[#<Nokogiri::XML::Attr:0x3ff14c533388 name="class" value="c0">] children=[#<Nokogiri::XML::Element:0x3ff14c532f50 name="td" children=[#<Nokogiri::XML::Element:0x3ff14c532d70 name="a" attributes=[#<Nokogiri::XML::Attr:0x3ff14c532d0c name="href" value="/worldclock/afghanistan/kabul">] children=[#<Nokogiri::XML::Text:0x3ff14c5328d4 "Afghanistan - Kabul">]>, #<Nokogiri::XML::Element:0x3ff14c532730 name="span" attributes=[#<Nokogiri::XML::Attr:0x3ff14c5326cc name="id" value="p0s">, #<Nokogiri::XML::Attr:0x3ff14c5326b8 name="class" value="wds">]>]>, #<Nokogiri::XML::Element:0x3ff14c537f78 name="td" attributes=[#<Nokogiri::XML::Attr:0x3ff14c537f14 name="id" value="p0">, #<Nokogiri::XML::Attr:0x3ff14c537f00 name="class" value="rbi">] children=[#<Nokogiri::XML::Text:0x3ff14c5378c0 "火曜日 18時51分">]>]>

てなのが出てきます。
こいつを順繰りにソートすれば目的は果たせそうです。

buff = doc.xpath("//table//tr[@class='c0']")
buff.each {|i| puts %Q(#{i.xpath(".//a").text} : #{i.xpath(".//td[@class='rbi']").text})}
Afghanistan - Kabul : 火曜日 18時51分
Argentina - Buenos Aires : 火曜日 11時21分
Australia - New South Wales - Sydney : 水曜日 0時21分
Australia - Queensland - Brisbane : 水曜日 0時21分
Australia - Victoria - Melbourne : 水曜日 0時21分
Austria - Vienna - Vienna : 火曜日 16時21分
...
Uruguay - Montevideo : 火曜日 11時21分
Venezuela - Caracas : 火曜日 9時51分
Zimbabwe - Harare : 火曜日 16時21分

いい感じです。
ただ、これだと毎度毎度検索しないといけないので

target = "China"
buff.each {|i| p i.text if i.xpath(".//a").text.include?(target) }
#>> "China - Beijing Municipality - Beijing火曜日 22時21分"

target = "Finland"
buff.each {|i| p i.text if i.xpath(".//a").text.include?(target) }
#>> "Finland - Helsinki *火曜日 17時21分"

参考もと