Código PHP:
<?php
/**
* El Tiempo: Baja los datos desde wunderground en formato CSV al
* archivo especificado en el constructor.
* Necesita CURL y PHP5 / Probado en PHP 5.3
*
* @author cosme
*/
class elTiempo {
private $separador = ".";
private $ano;
private $mes;
private $dia;
private $curl;
/**
* El Tiempo: Trae datos de temperatura por hora del dia especificado
* archivo especificado aqui
* @param type $saveTo Especifica el archivo a guardar
* @return type true
*/
public function __construct() {
ini_alter("set_time_limit", 0);
//inicializamos curl. Mejor ahorrar tiempo porque recibirá muchos request
$this->curl = curl_init();
curl_setopt($this->curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1");
curl_setopt($this->curl, CURLOPT_HEADER, false);
curl_setopt($this->curl, CURLOPT_COOKIEFILE, ".cookie");
curl_setopt($this->curl, CURLOPT_HTTPHEADER, array("Accept-Language: es-es,en"));
curl_setopt($this->curl, CURLOPT_COOKIEJAR, ".cookie");
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($this->curl, CURLOPT_TIMEOUT, 60);
curl_setopt($this->curl, CURLOPT_AUTOREFERER, TRUE);
return $this->setSeparador();
}
/**
* Esta funcion trae un array de objetos con los detalles por dia
* array[año/mes/dia/hora]->temp
* array[año/mes/dia/hora]->humedad
* array[año/mes/dia/hora]->rocio
* @param type $fecha en año/mes/dia
* @return array de objetos
*/
public function getDate($fecha) {
$tmp = explode("/", $fecha);
if (count($tmp) < 3)
die("Error al especificar el formato de fecha");
if (strlen($tmp[0]) != 4)
die("El año fue mal especificado");
//if (strlen($tmp[2]) != 2)
// die("El dia fue mal especificado");
//if (strlen($tmp[1]) != 2)
// die("El dia fue mal especificado");
if (!checkdate($tmp[1], $tmp[2], $tmp[0])) {
echo"Fecha Invalida\n";
return false;
}
$this->ano = (int) $tmp[0];
$this->mes = (int) $tmp[1];
$this->dia = (int) $tmp[2];
$this->diaPad = str_pad($this->dia, 2, 0, STR_PAD_LEFT);
$this->mesPad = str_pad($this->mes, 2, 0, STR_PAD_LEFT);
$this->anoPad = str_pad($this->ano, 2, 0, STR_PAD_LEFT);
$datos = $this->getOnline();
return $this->parseData($datos);
}
/**
* Esta funcion baja los datos de la pagina, usa CURL
* @return type
*/
private function getOnline() {
$url = "http://www.wunderground.com/history/airport/SCEL/$this->ano/$this->mes/$this->dia/DailyHistory.html ";
curl_setopt($this->curl, CURLOPT_URL, $url);
curl_setopt($this->curl, CURLOPT_POST, false);
curl_setopt($this->curl, CURLOPT_HEADER, true);
curl_setopt($this->curl, CURLOPT_REFERER, '');
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($this->curl);
if ($result === false) {
echo curl_error($this->curl);
}
return $result;
}
/**
* Este metodo baja la fecha, la limpia y lo guarda en un archivo.
* El archivo especificado debe ser un handle abierto con fopen
* @param type $fecha fecha en año/mes/dia
* @param type $file filehandle
* @return type
*/
public function getDateToFile($fecha, $file) {
$objs = $this->getDate($fecha);
foreach ($objs as $obj) {
$string = "$this->anoPad/$this->mesPad/$this->diaPad;$obj->hora;$obj->temp;$obj->rocio;$obj->humedad\n"; //row csv
fwrite($file, $string);
}
return true;
}
/**
* Esta funcion limpia los datos y los retorna en un arreglo de objetos
* @param type $datos recibe la pagina descargada con CURL
* @return type array de objetos
*/
public function parseData($datos) {
$datos = explode("<div id=\"observations_details\" class=\"\">", $datos);
$tmp = explode("<tr", $datos[1]); //rows
$objetos = array();
foreach ($tmp as $row) {//REVISANDO ROWS
$col = explode("<td >", $row);
if (count($col > 5) && isset($col[1])) {//proteccion: por si la columna no tiene los datos
$tmp_hora = explode("</td>", $col[1]);
$hora = $tmp_hora[0];
if (!checkdate($this->mes, $this->dia, $this->ano))
continue;
if ($hora !== "") {//si tengo hora continuo
switch ($hora) {
case "12:00 AM":
$hora = "24";
break;
case "1:00 AM":
$hora = "01";
break;
case "2:00 AM":
$hora = "02";
break;
case "3:00 AM":
$hora = "03";
break;
case "4:00 AM":
$hora = "04";
break;
case "5:00 AM":
$hora = "05";
break;
case "6:00 AM":
$hora = "06";
break;
case "7:00 AM":
$hora = "07";
break;
case "8:00 AM":
$hora = "08";
break;
case "9:00 AM":
$hora = "09";
break;
case "10:00 AM":
$hora = "10";
break;
case "11:00 AM":
$hora = "11";
break;
case "12:00 PM":
$hora = "12";
break;
case "1:00 PM":
$hora = "13";
break;
case "2:00 PM":
$hora = "14";
break;
case "3:00 PM":
$hora = "15";
break;
case "4:00 PM":
$hora = "16";
break;
case "5:00 PM":
$hora = "17";
break;
case "6:00 PM":
$hora = "18";
break;
case "7:00 PM":
$hora = "19";
break;
case "8:00 PM":
$hora = "20";
break;
case "9:00 PM":
$hora = "21";
break;
case "10:00 PM":
$hora = "22";
break;
case "11:00 PM":
$hora = "23";
break;
default:
$hora = false;
break;
}
if ($hora) { //Si es una hora cerrada
$obj = new stdClass();
$obj->hora = $hora;
$temp;
preg_match_all("/<span class=\"b\">(.*?)<\/span>/", $col[2], $temp);
if (isset($temp[1][0]))
$obj->temp = str_replace(".", $this->separador, $temp[1][0]);
$rocio;
preg_match_all("/<span class=\"b\">(.*?)<\/span>/", $col[3], $rocio);
if (isset($rocio[1][0])) {
$obj->rocio = str_replace(".", $this->separador, $rocio[1][0]);
} else {
$obj->rocio = "";
}
$humedad = explode("</td>", $col[4]);
$obj->humedad = str_replace(".", $this->separador, $humedad[0]);
$objetos["$this->ano/$this->mes/$this->dia/$hora"] = $obj;
}
}
}
}//FIN REVISION ROWS
//Fix horas que no aparecen, deben aparecer con datos null
if (checkdate($this->mes, $this->dia, $this->ano)) {
for ($hora = 1; $hora < 25; $hora++) {
$horaPad = str_pad($hora, 2, 0, STR_PAD_LEFT);
if (!isset($objetos["$this->ano/$this->mes/$this->dia/$horaPad"])) {
$obj = new stdClass();
$obj->rocio = "";
$obj->humedad = "";
$obj->temp = "";
$obj->hora = $horaPad;
$objetos["$this->ano/$this->mes/$this->dia/$horaPad"] = $obj;
} else {
$obj = $objetos["$this->ano/$this->mes/$this->dia/$horaPad"];
}
}//fin arreglos por hora
}
//ordenamientos de objeto por el pedido
$order = array();
for ($i = 1; $i < 25; $i++) {
$iPad = str_pad($i, 2, "0", STR_PAD_LEFT);
$order["$this->ano/$this->mes/$this->dia/$iPad"] = $objetos["$this->ano/$this->mes/$this->dia/$iPad"];
}
return $order;
return true;
}
/**
* setea el separador decimal, en caso de querer cambiarlo
* @param type $separador
*/
public function setSeparador($separador = ",") {
$this->separador = $separador;
return true;
}
public function __destruct() {
curl_close($this->curl);
ini_restore("set_time_limit");
}
}
?>