一般获取天气预报信息的方式有两种
1,调用第三方的api,获取需要信息
2,抓取网页内容,通过正则表达式匹配获得需要信息
当然你也可以直接找中央气象局的相关单位,从他们那里直接取得数据。
这里以Google的api为例,之所以没用雅虎的api是因为它的中国城市太少了,至少我在的无锡都没有
http://www.google.com/ig/api?hl=zh_CN&weather=wuhan 打开这个网址可以看到Google的返回结果
思路:
1,请求api地址,获取结果
2,将结果转换为dom文档
3,从dom文档中提取信息
一下为实现代码
require "net/http"
require "uri"
require "rexml/document"
require "iconv"
class Weather
WEATHER_URI = "http://www.google.com/ig/api?hl=en&weather=%city%"
# WEATHER_URI = "http://www.google.com/ig/api?hl=zh_CN&weather=%city%" # 包含中文的xml会解析失败,不知道为什么?
def initialize(city="beijing")
@city = city.strip
end
#取得天气预报结果,一个包含4个hash对象的数组
def weather_data
xml = xml_document
data = []
xml.root.get_elements("/xml_api_reply/weather/forecast_conditions").each do |element|
data << parse_element(element)
end
data
end
#解析xml文档单个元素,返回一个hash对象
def parse_element(element)
ha = {}
low_element = element.get_elements("low")[0]
high_element = low_element.next_element
icon_element = high_element.next_element
condition_element = icon_element.next_element
ha[:low] = to_c(low_element.attributes["data"].to_i)
ha[:high]= to_c(high_element.attributes["data"].to_i)
ha[:icon]= icon_element.attributes["data"]
ha[:conditon] = condition_element.attributes["data"]
ha
end
# 转换到摄氏度
def to_c(f)
(f - 32) * 5 / 9+1
end
#取得返回的xml文档
def xml_document
uri = WEATHER_URI.gsub(/%city%/,@city)
res = Net::HTTP.get_response(URI.parse(uri)).body
REXML::Document.new(res)
end
#类方法,方面调用,也算是入口
def self.get_weather(city=nil)
if city
self.new(city.strip).weather_data
else
self.new("beijing").weather_data
end
end
end
# ==================以下为在命令行输出之用===============
def day(num)
case num
when 0
"今日"
when 1
"明日"
when 2
"后天"
when 3
"大后天"
else
raise ""
end
end
i = 0
we = Weather.get_weather ARGV[0].strip
we.each do |w|
s = "#{day(i)},最高温度:#{w[:high]},最低温度:#{w[:low]},天气:#{w[:conditon]}"
s = Iconv.iconv("GB2312", "UTF-8", s) #在win命令行下显示中文
puts s
i+=1
end
测试
D:\myruby\study\RubyStudy\lib>ruby Weather.rb wuhan
今日,最高温度:29,最低温度:21,天气:Thunderstorm
明日,最高温度:27,最低温度:24,天气:Chance of Storm
后天,最高温度:29,最低温度:23,天气:Rain
大后天,最高温度:28,最低温度:23,天气:Thunderstorm
D:\myruby\study\RubyStudy\lib>ruby Weather.rb beijing
今日,最高温度:29,最低温度:21,天气:Chance of Rain
明日,最高温度:29,最低温度:21,天气:Chance of Rain
后天,最高温度:31,最低温度:22,天气:Chance of Rain
大后天,最高温度:36,最低温度:21,天气:Chance of Rain
两个缺陷
1,天气状况还未中文化,这属于我的原因,未进行中文化处理
2,Google的api貌似也不可靠,比如查询wuxi,有时就会显示没有相关信息。