quando procurei há uns 3 meses atrás, todas que achei eram ou desatualizadas ou utilizavam algum serviço pago. Hoje utilizo o OpenWeatherMap em conjunto com o Yahoo Weather. Basicamente você tem que chamar uma URL que contém o código da cidade e o serviço vai te retornar algum xml ou json.
Ex. Open Weather Map
o campo id é o código interno da cidade, no caso de São Paulo, o 3448439
Ex. Yahoo Weather
* para descobrir o código da cidade: vá em
http://weather.yahoo.com/ e digite São Paulo. Ao ver a previsão, vai aparecer o id na url. No caso de São Paulo é o 455827.
1. o Yahoo gera XML, então tem que usar o método Hash.from_xml e to_hash. O OWM usa JSON então tem que usar o JSON.parse
2. nunca faça uma chamada por página. Isto é muito lento, e se o serviço estiver fora o seu site pode cair também. E estas APIs limitam o número de chamadas por dia. Ao invés disto chame de 15 em 15 minutos ou use um intervalo maior. Use um sistema de cache (ex. redis) para isto e na página somente use o caché que será atualizado por outro processo.
3. na minha cidade o OWM retorna precisamente a temperatura atual, mas insiste em colocar a máxima e mínima com os mesmos valores. Já o Yahoo, aqui mostra a temperatura relativa e não a atual. O que eu faço é pegar a temperatura atual do OWM e a mínima/máxima do Yahoo.
Snippet de como pegar os dados:
require 'net/http'
require 'uri'
# open weather
open_weather = {
"temp_now" => doc["main"]["temp"].round,
"temp_max" => doc["main"]["temp_max"].round,
"temp_min" => doc["main"]["temp_min"].round,
"condition_code" => doc["weather"][0]["id"]
}
# yahoo weather
yahoo_weather = {
"temp_now" => doc["rss"]["channel"]["item"]["condition"]["temp"],
"temp_max" => doc["rss"]["channel"]["item"]["forecast"][0]["high"],
"temp_min" => doc["rss"]["channel"]["item"]["forecast"][0]["low"]
}