`
酷的飞上天空
  • 浏览: 517749 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

基于google的weatherAPI的天气预报

阅读更多

一般获取天气预报信息的方式有两种

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,有时就会显示没有相关信息。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics