Pegando a temperatura de qualquer cidade

julho 29th, 2010 por caferrari Leave a reply »

Me surgiu um trabalho aqui pelo qual preciso exibir a temperatura atual da cidade, e como estava com insônia decidi brincar um pouco e criar uma solução para isso, fui para o google e pesquisei por “Previsão do Tempo“, me surgiram alguns resultados, porém, gostei mais do UOL.

Depois disso foi correr para a criação do script para ler o HTML e retornar um objeto contendo as informações da temperatura no momento, segue o código escrito em php:

function loadTemp($cidade='Palmas-TO'){
	// variavel para dados de retorno
	$ret = array('url' => "http://tempoagora.uol.com.br/previsaodotempo.html/brasil/$cidade/");
 
	// carrega o html do tempoagora
	$html = file_get_contents($ret['url']);
 
	// Pegamos apenas a parte que interessa do html
	$iniflag = '<!-- Insere dados Atuais de AeroPortos ou Est. Meteorologica -->';
	$fimflag = '<!-- FIM Insere dados Atuais de AeroPortos ou Est. Meteorologica -->';
	$ini = strrpos($html, $iniflag ) + strlen($iniflag);
	$fim = strpos($html, $fimflag, $ini);
	$html = substr($html, $ini, ($fim-$ini));
 
	// pegamos a url do icone
	preg_match('@<img src="/(imagens/icones/[a-zA-Z\-]+.gif)"@', $html, $mat);
	$ret['icone'] = 'http://tempoagora.uol.com.br/' . $mat[1];
 
	// Limpa o código html
	$content = strip_tags($html);
	$content = str_replace('&nbsp;', ' ', $content);
 
	// quebra o que sobrou em um vetor
	$content = explode("\n", $content);
 
	// limpa espaços e linhas em branco
	foreach ($content as $k => &$v){
		$v = trim($v);
		if ($v==='') unset($content[$k]);
	}
 
	// pega horário da verificação
	$lin = array_shift($content);
	preg_match('@[0-9]{1,2}:[0-9]{1,2}@', $lin, $mat);
	$ret['verificado']  = $mat[0];
 
	// pega insidência de nuvens
	$ret['nuvens'] = array_shift($content);
 
	// define nomes melhores para as próximas propriedades
	$keys = array('temperatura', 'sensacao', 'vento', 
			'pressao', 'umidade', 'visibilidade');
 
	// reseta as chaves do vetor
	$content = array_unique($content);
 
	// percorre chaves impares e aplica as propriedades definidas acima
	for ($x=1; $x<=11; $x=$x+2){
		$ret[array_shift($keys)] = $content[$x];
	}
 
	// retorna os dados como um objeto
	return (object)$ret;
}

Analisando o site deles, notei que a temperatura é atualizada de hora em hora, então a melhor forma de utilizar essa solução é utilizando o crontab, que executa a cada hora, eu escolhi executar no quinto minuto de cada hora cheia (5:05, 6:05, etc).

segue o código php que o crontab executa:

require 'loadTemp.php';
// define nome do arquivo de cache
$cache_file = sys_get_temp_dir() . '/temp';
 
// carrega a temperatura
$temp = loadTemp();
 
// salva em cache
file_put_contents($cache_file, serialize($temp));

E para exibir no sistema eu fiz uma funçãozinha:

function temp(){
	$cache_file = sys_get_temp_dir() . '/temp';
	// se o cache existe, retorna o objeto
	if (file_exists($cache_file)) 
		return unserialize(file_get_contents($cache_file));
 
	// senão cria o cache e retorna =)
	$temp = loadTemp();
	file_put_contents($cache_file, serialize($temp));
	return $temp;
}

depois, no local específico, ficou algo mais ou menos assim:

<?php $temp = temp() ?>
<img src="<?php echo $temp->icone ?>" alt="<?php echo $temp->nuvens ?>" />
<span><?php echo $temp->temperatura ?> (<a rel="external" href="<?php echo $temp->url ?>">saiba mais</a>)</span>

Minha forma de pagar por esse uso é manter um link para o Tempoagora, o que é bastante interessante, pois meu visitante pode querer obter mais informações

É isso ai, abraço a todos

Advertisement

10 comments

  1. Muito interessante, veio! Show de bola!

    No início do post eu achei que a função fosse JavaScript. Você comentou algo sobre HTML e JS… Mas no fim está muito show!
    Você poderia colocar um *.php de exemplo no servidor rodando isso aí pra gente ver. Poderia atualizar em cada request mesmo, já que a visitação supostamente será pequena.

  2. O teu código está totalmente dependente da estrutura do site da uol, além do mais a cada requisição ele tem que baixar o HTML de uma página inteira.

    Eu sugiro a utilização de APIs que existem. O proprio Google e o Yahoo fornecem ótimas interfaces para o acesso dessas informações.

    ;)

  3. Thiago Belem disse:

    Concordo com o Molin… Se eles mudam o HTML do site o seu “sistema” para de funcionar na hora :P

  4. É um método.

    Eu prefiro a API do Google. Um link de exemplo: http://www.google.com/ig/api?weather=S%C3%A3o+Paulo

    O retorno é um XML, e contem até mesmo a URL da imagem de sol, chuva, nublado etc.

    Um sugestão para seu post é a seguinte: possivelmente a API do Google ou o próprio site do UOL esteja nalgum dia indisponível. Se houver indisponibilidade no Google, pega automaticamente do UOL. É uma forma de prover segurança.

    Um abraço.

  5. Muito bom,
    Posso dizer que esse é meu trabalho, fazer raspagem de dados, porem, faço de dados governamentais.
    Teu codigo esta muito bom,porém muito grande, Tenho um pequeno projeto no github chamado curioso.
    Para pegar a imagem do tempo atual tu iria fazer assim

    $url = “http://tempoagora.uol.com.br/previsaodotempo.html/brasil/Palmas-TO”
    $xpath = “/html/body/div/div/div[4]/div[4]/div[2]/table/tbody/tr/td/img”

    $curioso = new Curioso();
    $img = $curioso->scrap($url, $xpath)

    isso te voltaria um xml com a tag img

    mais depois de instaciar o curioso voce poderia pedir isso de outra forma assim:

    $curioso = new Curioso();
    $curioso->format=”object”; //can be (object | xml | array | json)
    $img = $curioso->scrap($url, $xpath)

    e de voltaria um objeto do php, voce pode pedir json e array ainda.

    Qualquer coisa da uma olhada http://github.com/emersonvinicius/Curioso
    e quem quiser melhorar só da um toque que eu dou permissão no repositorio

  6. Ah, sobre as API, para o tempo funciona, mais e se quiser pegar outros dados que não tem api?

    Porisso acho que vale o codigo.
    E essa abordagem que o Ferrari fez ainda não tinha pensando.

    Muito bom o post

  7. Lucas Gameiro disse:

    Sempre que possível é melhor utilizar uma API do que ficar dependente da estrutura de um site.
    Porém o maior problema com este script IMHO é a utilização do file_get_contents. O cURL foi feito pra isso e é muito mais rápido para acessar páginas. Este link mostra bem isso: http://stackoverflow.com/questions/555523/file-get-contents-vs-curl-what-has-better-performance

    @Emerson: Você pode lavar o cabelo e o corpo com o sabonete. Você vai desisitir de usar shampoo por causa disso?

  8. @Lucas: juro que tentei mais não entendi sua piada

    O que disse sobre API, foi o seguinte, dados como tempo, mapas, cep e outras tem API, o que é melhor com certeza usa-las, mais se você quiser pegar algum dado que não tem API?
    no caso eu uso YQL

  9. gilberto disse:

    caraca car coloquei esse codigo no minha radio onlaine usando o zara radio e ficou show para bems mais tinha que postar em html valeu

  10. Ta mas como isso vai parar por exemplo na minha página inicial como montar…. mim responda por e-mail por favor!! desde já grato….

Deixe uma resposta