Scraping por linguagem 9 min de leitura

Scraping de dados meteorológicos: fontes, APIs e implementações em várias linguagens

De onde obter dados meteorológicos: APIs abertas, dados abertos do INMET, scraping de sites agregadores e implementação do coletor em várias linguagens.

EW
Equipe Web-Scraping.biz
Coleta de dados para as demandas do negócio
Publicado: 3 abril 2025

A previsão do tempo é um daqueles blocos que elevam o valor de um site sem fazer barulho: o usuário passa mais tempo na página, volta com mais frequência e o conteúdo é percebido como «vivo». Por isso os widgets e blocos meteorológicos são tão frequentes nos portais urbanos e turísticos, nos serviços de reservas e nos sites de imóveis no exterior. Neste artigo, repassamos de onde obter dados meteorológicos, quais APIs são populares em 2026, em que o parsing de HTML difere do trabalho por meio de uma API, e mostramos implementações prontas em Python, JavaScript, PHP e Go.

O que é o «scraping do tempo» e que abordagens existem

Sob o rótulo de «scraping do tempo» costumam se agrupar duas tarefas de natureza distinta:

  1. Trabalhar por meio de uma API oficial. O serviço entrega dados estruturados (quase sempre JSON): dispara-se uma requisição HTTP e recebem-se campos prontos — temperatura, umidade, velocidade do vento, código do fenômeno meteorológico. É a via confiável, legal e previsível.
  2. Scraping de páginas HTML. Quando a fonte não oferece API ou ela é paga, os desenvolvedores extraem os dados diretamente do markup do site. Funciona, mas é frágil: qualquer mudança no HTML quebra o scraper, e a própria abordagem viola com frequência as condições de uso da fonte.

A conclusão prática é simples: sempre que existir uma API, use a API. Reserve o scraping para quando realmente não houver outra fonte e, em todo caso, verifique o robots.txt e as condições de uso.

Fontes de dados e APIs populares

Open-Meteo: gratuito e sem chave

O Open-Meteo é uma das opções mais convenientes para começar. A API não exige chave para uso não comercial, devolve os dados em JSON e agrega as previsões dos serviços meteorológicos nacionais com resolução de 1 a 11 km. Para projetos comerciais existem planos pagos à parte, com limites mensais de requisições. Ideal para protótipos, widgets e projetos open source.

OpenWeatherMap: o clássico com um limite gratuito amplo

O OpenWeatherMap segue sendo o serviço mais repetido nos tutoriais. Em 2026, conserva uma via gratuita operacional, mas importa entender qual produto exato está sendo chamado. Os endpoints clássicos (tempo atual, previsão a cada 3 horas, poluição do ar, mapas meteorológicos, geocodificação) estão disponíveis de graça com um limite de 60 requisições por minuto e até 1 000 000 de requisições por mês. Os produtos da família One Call (3.0 / 4.0) são assinaturas à parte, com cobrança por chamada e as primeiras 1000 requisições diárias gratuitas. Antes de ir para produção, vale definir um teto de gasto para não ultrapassar por acidente o limite gratuito.

WeatherAPI.com: um plano gratuito generoso

O WeatherAPI.com serve o tempo atual, a previsão horária e diária, dados históricos, astronomia e geolocalização, em JSON e XML. Uma escolha conveniente quando se busca um único provedor «para tudo» com um limite gratuito claro.

Visual Crossing: dados históricos potentes

O Visual Crossing é citado com frequência entre os melhores em relação custo-benefício: uma única API para o tempo atual, as previsões, os alertas e, sobretudo, séries históricas longas. Há chave gratuita e um Query Builder para montar consultas com exportação para JSON ou CSV. Boa opção para análise de dados e dashboards.

Plataformas para empresas: Tomorrow.io, Weatherbit, Meteomatics, meteoblue

Se forem necessários parâmetros muito especializados (cerca de 500 no Tomorrow.io, mais de 1800 no Meteomatics, séries históricas desde 1940), olhe para as plataformas corporativas. Elas oferecem alta precisão e um leque enorme de parâmetros, mas quase sempre exigem assinatura paga para uso comercial.

A fonte oficial do Brasil: INMET

O INMET, Instituto Nacional de Meteorologia, é o serviço meteorológico oficial do Brasil, e seu portal de dados abertos é a referência para projetos focados no país. O instituto mantém uma rede de centenas de estações meteorológicas automáticas e convencionais em todo o território e publica gratuitamente observações das estações, previsões por município, alertas e longas séries climatológicas.

Uma particularidade que vale conhecer: boa parte do acervo histórico é distribuída como arquivos CSV organizados por estação e por período — um formato pensado para download e análise, não para consultas pontuais. As estações são identificadas por códigos próprios, e os municípios seguem a codificação do IBGE. Os dados são reutilizáveis com citação do INMET como fonte, nas condições habituais dos dados abertos.

Serviços estatais e oficiais

Para os Estados Unidos existe a API gratuita e sem chave do Serviço Meteorológico Nacional (NWS, weather.gov): uma opção excelente para projetos civis e comunitários dentro do país. No Brasil, esse papel cabe ao INMET, com seu portal de dados abertos descrito acima, e os serviços meteorológicos nacionais de outros países mantêm portais de dados abertos semelhantes. As fontes estatais são gratuitas e confiáveis, mas costumam se limitar a um território específico.

Comparação por critérios-chave

Fonte Chave Plano gratuito Cobertura Ideal para
Open-Meteo Não exige (não comercial) Sim, generoso Global Protótipos, widgets, open source
OpenWeatherMap Exigida Sim (endpoints clássicos) Global Tarefas universais
WeatherAPI.com Exigida Sim Global «Tudo em um»
Visual Crossing Exigida Sim Global Histórico, análise de dados
Tomorrow.io / Meteomatics Exigida Teste/limite Global Negócios, parâmetros específicos
INMET (dados abertos) Não exige (dados abertos) Sim (dados abertos) Brasil Projetos focados no Brasil
NWS (weather.gov) Não exige Sim Somente EUA Projetos civis nos EUA

Implementações em várias linguagens

Em todos os exemplos a seguir, usa-se o Open-Meteo, porque não precisa de chave: o código pode ser executado como está. As coordenadas dos exemplos correspondem a São Paulo (-23.55, -46.63). Para migrar a outro provedor, costuma bastar trocar a URL, adicionar a chave e ajustar o parsing do JSON.

Python (requests)

python
import requests

def get_weather(lat: float, lon: float) -> dict:
    url = "https://api.open-meteo.com/v1/forecast"
    params = {
        "latitude": lat,
        "longitude": lon,
        "current": "temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code",
        "timezone": "auto",
    }
    response = requests.get(url, params=params, timeout=10)
    response.raise_for_status()
    return response.json()

data = get_weather(-23.55, -46.63)
current = data["current"]
print(f"Temperatura: {current['temperature_2m']}°C")
print(f"Umidade: {current['relative_humidity_2m']}%")
print(f"Vento: {current['wind_speed_10m']} km/h")

Versão para o OpenWeatherMap com chave e localização em português:

python
import requests

API_KEY = "SUA_CHAVE"

def get_weather_owm(city: str) -> dict:
    url = "https://api.openweathermap.org/data/2.5/weather"
    params = {"q": city, "units": "metric", "lang": "pt_br", "appid": API_KEY}
    response = requests.get(url, params=params, timeout=10)
    response.raise_for_status()
    d = response.json()
    return {
        "cidade": d["name"],
        "temperatura": d["main"]["temp"],
        "sensacao": d["main"]["feels_like"],
        "descricao": d["weather"][0]["description"],
    }

print(get_weather_owm("São Paulo"))

JavaScript / Node.js (fetch nativo)

No Node.js 18+, o fetch já vem disponível por padrão: não é preciso instalar dependências externas.

javascript
async function getWeather(lat, lon) {
  const url = new URL("https://api.open-meteo.com/v1/forecast");
  url.searchParams.set("latitude", lat);
  url.searchParams.set("longitude", lon);
  url.searchParams.set("current", "temperature_2m,wind_speed_10m,weather_code");
  url.searchParams.set("timezone", "auto");

  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Erro HTTP: ${response.status}`);
  }
  return response.json();
}

getWeather(-23.55, -46.63)
  .then((data) => {
    const c = data.current;
    console.log(`Temperatura: ${c.temperature_2m}°C, vento: ${c.wind_speed_10m} km/h`);
  })
  .catch((err) => console.error("Não foi possível obter os dados do tempo:", err.message));

PHP (cURL)

php
<?php
function getWeather(float $lat, float $lon): ?array
{
    $query = http_build_query([
        'latitude'  => $lat,
        'longitude' => $lon,
        'current'   => 'temperature_2m,wind_speed_10m,weather_code',
        'timezone'  => 'auto',
    ]);
    $url = "https://api.open-meteo.com/v1/forecast?{$query}";

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_USERAGENT      => 'WeatherWidget/1.0',
    ]);
    $body = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($body === false || $code !== 200) {
        return null;
    }
    return json_decode($body, true);
}

$data = getWeather(-23.55, -46.63);
if ($data !== null) {
    echo "Temperatura: " . $data['current']['temperature_2m'] . "°C\n";
}

Go

go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"
)

type WeatherResponse struct {
    Current struct {
        Temperature float64 `json:"temperature_2m"`
        WindSpeed   float64 `json:"wind_speed_10m"`
        WeatherCode int     `json:"weather_code"`
    } `json:"current"`
}

func main() {
    url := "https://api.open-meteo.com/v1/forecast" +
        "?latitude=-23.55&longitude=-46.63" +
        "&current=temperature_2m,wind_speed_10m,weather_code&timezone=auto"

    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Get(url)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var data WeatherResponse
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
        panic(err)
    }
    fmt.Printf("Temperatura: %.1f°C, vento: %.1f km/h\n",
        data.Current.Temperature, data.Current.WindSpeed)
}

Dados históricos do INMET (medições das estações automáticas)

bash
# Localize no portal de dados abertos do INMET o conjunto desejado
# (por exemplo, o arquivo anual com as medições das estações automáticas)
# e baixe o CSV compactado a partir da URL indicada no portal
curl -O "URL_DO_ARQUIVO_NO_PORTAL"

Cada arquivo reúne as medições de uma estação (temperatura, umidade, vento, precipitação) em intervalos horários; as previsões por município usam os códigos do IBGE. Antes de ir para produção, confira os endpoints e os formatos na documentação oficial do portal.

O scraping de HTML como plano B (Python + BeautifulSoup)

Quando não há API disponível, os dados podem ser extraídos do markup. A abordagem funciona, mas é frágil: se o HTML muda, os seletores deixam de servir, e só é admissível usá-la se não contrariar as condições da fonte.

python
import requests
from bs4 import BeautifulSoup

def scrape_weather(url: str) -> str:
    headers = {"User-Agent": "Mozilla/5.0"}
    html = requests.get(url, headers=headers, timeout=10).text
    soup = BeautifulSoup(html, "html.parser")
    # O seletor é ajustado à página de origem específica
    temp = soup.select_one(".temperature")
    return temp.get_text(strip=True) if temp else "não encontrado"

A decodificação do weather_code no Open-Meteo segue o padrão da WMO: por exemplo, 0 — céu limpo, 2 — nebulosidade variável, 61 — chuva fraca, 71 — neve fraca. Mantenha a tabela completa de códigos como um dicionário de mapeamento para exibir ao usuário uma descrição legível.

Cache, limites e questões legais

Algumas regras que economizam dinheiro e dores de cabeça em produção:

  • Faça cache das respostas. O tempo quase nunca precisa ser atualizado a cada visualização de página. Faça cache por coordenadas, cidade ou CEP e renove as condições atuais a cada 5--15 minutos. Nos aplicativos móveis, encaminhe as requisições pelo seu próprio backend em vez de dispará-las de cada cliente.
  • Guarde as chaves no servidor. A chave de API não deve ser embutida no código cliente: é fácil roubá-la. As requisições devem passar pelo seu proxy de backend.
  • Monitore os limites. Configure o tratamento das respostas 401 (chave incorreta) e 429 (limite excedido) e alertas para um crescimento brusco no número de chamadas.
  • Verifique a licença. A maioria dos planos gratuitos só permite uso não comercial. Alguns serviços (Visual Crossing, OpenWeatherMap) admitem uso comercial limitado com citação da fonte. Para o scraping, revise sempre o robots.txt e as condições de uso.

Onde se aplica: portais, turismo e imobiliário

Um bloco meteorológico é o complemento típico dos projetos ligados à geografia e ao estilo de vida do usuário:

  • Os portais urbanos mostram o tempo atual e a previsão na página inicial: isso retém a audiência e transforma o site em um ponto de entrada diário.
  • Os portais turísticos e os serviços de reservas adicionam o tempo à página do destino: para o viajante, importa saber o que o espera na chegada.
  • Os sites de imóveis no exterior usam o tempo como parte da «venda do clima»: dias ensolarados, invernos suaves e temperaturas agradáveis são um argumento de peso na escolha de um imóvel à beira-mar ou na montanha.

O curioso é que, tecnicamente, o scraping do tempo pertence à mesma família de outra tarefa popular desses projetos: a coleta e agregação de anúncios. Se o tempo faz a página do destino parecer «viva», preencher o catálogo de imóveis é tarefa do scraping imobiliário: coleta automática de ofertas nos portais de origem, normalização de preços e características, atualização da base. Muitas vezes os dois módulos trabalham lado a lado: um cuida do conteúdo do imóvel e o outro, do contexto que o cerca.

Conclusão

Para a maioria das tarefas, o sensato é começar pelo Open-Meteo (início imediato, sem chave) ou pelo OpenWeatherMap (limite gratuito amplo e um ecossistema maduro). Se os dados históricos pesam, olhe para o Visual Crossing; se o projeto é focado no Brasil, a fonte oficial é o INMET. Tecnicamente, a integração ocupa poucas linhas em qualquer linguagem: requisição HTTP, parsing do JSON, cache. E um bloco do tempo bem integrado eleva de forma notável o engajamento nos portais urbanos, turísticos e imobiliários — ali onde ao usuário importa não só o objeto em si, mas também o contexto que o cerca.