Ejemplo de un filtrador de noticias : fetching
Escrito el 22/October/2007 por juan_belon
Hoy aprenderemos cómo cargar una página web externa y "pelar" el contenido de la "patata" para quedarnos sólo con lo que nos interesa así como formatear el resultado.
Lo primero que necesitamos para realizar nuestro script es una URL objetivo y el fichero de caché donde se escribirá cada día,para ello declaramos las siguientes variables:
<?php
$f = ‘/ruta_completa_al_directorio_de_caché/granada.xml';
$url = "http://es.noticias.yahoo.com/rss/granada.xml";
?>
de forma que lo primero que haremos será comprobar si disponemos de tal fichero para descargarlo en caso de que no sea así:
___PHP___
if (!file_exists($f) //Existe el fichero?
|| (date("d/m/Y",filemtime($f))-date("d/m/Y"))<0) //si,existe, tiene más de un día?
{ //en tal caso lo borramos
@unlink($f); //Recordar que @ se pone para que no se disparen posibles errores
//damos por supuesto que tanto el directorio como el fichero tiene permisos de escritura
$contenido = file_get_contents($url);
$fp = fopen($f,'w');
fwrite($fp,$contenido);
fclose($fp);
}
___PHP___
Una vez dispuesto el contenido que queremos "maquillar" primero extrayéndole la información que necesitamos,leemos el fichero final en la misma variable por aquello de la eficiencia en espacio,reutilizando la misma variable (si es que se hubiera utilizado anteriormente):
<?php
$contenido = file_get_contents($f);
?>
Con el contenido en memoria empezamos a "recortar" el contenido que nos interesa:
___PHP___
preg_match_all('/<item>.*<\/item>/isU',$contenido,$noticias);
___/PHP___
con esta expresión regular obtenemos todos los items del canal RSS de forma que nos quedamos con las $noticias (un array), del contenido, ahora sólo tenemos que iterar entre dichos elementos para ir extrayendo los títulos,enlaces y html que tiene cada uno de los items…
___PHP___
echo ‘<ul>';
$n = sizeof($noticias[0]);
for ($i=0; $i<$n; $i++){
preg_match("/<title>.*<\/title>/isU",$noticias[0][$i],$titulo);
$titulo = str_replace(array("<title>","</title>"),"",$titulo[0]);
preg_match('/<guid (.*)>(.*)<\/guid>/isU',$noticias[0][$i],$enlace);
$enlace = preg_replace('(<guid isPermaLink="false">)',"",$enlace[0]);
$enlace = ‘<a href="http://es.noticias.yahoo.com'.
utf8_decode(str_replace("</guid>","",$enlace)).'">ver</a>';
preg_match('/<media:text type="html">(.*)<\/media:text>/isU',$noticias[0][$i],$html);
$html = (str_replace(array('<media:text type="html">','</media:text>'),"",$html[0]));
$titulo = utf8_decode(str_replace(array('<![CDATA[',']]>'),array(""),$titulo));
echo ‘<li>'.$titulo.'<br>'.$html.'<br>'.$enlace.'<br></li>
‘;
}
echo ‘</ul>';
___/PHP___
Ésto convierte todo el XML en un nuevo código HTML con una lista (<UL></UL>) de elementos con noticias y enlaces más una pequeña descripción en HTML.
Espero que os haya servido la explicación.
Saludos.
Seguir las respuestas con el canal RSS 2.0 para ello. Ir al final para comentar. "Pinging" no permitido.
hayyy juan, esta muy bien explicado, todo perfecto, pero ese script puede asesinar cualquier tipo de servidor en lo que se ejecute unas cuantas veces por minuto, hay que leer un feed en otro servidor, parsearlo al completo y luego escudriñar en el para luego mostrarlo. hasta hace 1 o 2 años esto era necesario, es mas, era la unica forma, yo preferia tener un archivo que iciera la captura y por un crontab programar que todos los dias leyera una lista de feeds y guardara resultados, evitaba a cada usuario la carga del xml, el parseado y la busqueda. Con php 5 tenemos la posibilidad de leer tags de archivos sin necesidad de preg_match_all() incluso los atributos de los tags, solo lo fui investigando y me fui quedando cada vez mas flipao, mirad la documentacion aqui:http://es.php.net/manual/es/ref.xml.php bueno he hestado un poco liado, pero pienso hacer algun tutorial de esto, y tambien os pongo un ejemplo que hize algun tiempo para un sistema de noticias:
$mi = "sql2noticias.xml";
$xml = @simplexml_load_file($mi) or die ("no se puede cargar");
$res['titulo'] = $xml->titulo;
$res['descripcion'] = $xml->descripcion;
$res['contenido'] = $xml->contenido;
$res['imagen1′] = $xml->imagen1;
$res['imagen2′] = $xml->imagen2;
$res['imagen3′] = $xml->imagen3;
$res['imagenp1′] = $xml->imagenp1;
$res['imagenp2′] = $xml->imagenp2;
$res['imagenp3′] = $xml->imagenp3;
echo "".$res['titulo']."".$res['descripcion']."".$res['contenido'];
tan simple como eso evitamos toda la parafernalia de el parseamiento, es mas, con un bucle for se podria autoespecificar y automostrar los diferentes tags en caso de que alguno de ellos no sieguiese la estandarizacion
Un abrazo chicos, buen trabajo
NOTA MENTAL: SOLO PHP 5, ESTO ES NUEVO.
A LIARLAAAA
Muchas gracias por la versión para PHP5 Pabloko, estaría bien que explicaras cómo se hace lo del cron
saludos!
Fuf, cron y sus contabs, en verdad tengo bastante poca información sobre este aspecto… depende de las caracteristicas del servidor por ejmplo mis serviidores lo llevan por defecto, en el cPanel lo podemos encontrar, es simplemente un componente que llama a shell a ejecutar algo en un intervalo de tiempo determinado.
En servidores UNIX un cron valido seria algo como start cron -crontab lib/php/php5 * /root/www/ruta/p.php * * * * 1
donde los arteriscos corresponden a intervalo de tiempo, este estara mal pero corresponde a ejecutar el archivo cada segundo, las peticiones, al no ser modo browser, producen un resultado que en vez de mostrarse en un navegador son enviadas por correo y guardadas en un log, en windows se hace con acceso shell, net start cron (si wel servicio cronW esta corriendo) y lueog la definicion.
Si os fijais es una tarea programada que puede extraer las RSS de nuestro blogroll y procesarlas una vez al dia y tener el sistema al rapido para los usuarios sin tener que procesar peticiones continuamente
actualmente tengo funcionando uno que extrae del INM el tiempo todos los dias y mediante un api cada cual lo mistra en su web con su codigo
Tambien estuvo habilitada (esta se parseaba con preg_match_all) una redaccion de un periodico recibiendo todos los datos xml de los mas importantes medis para elegir si publicarlos y ordenarlos en el diario digital
util sencillo y rapido, como to lo ke traigo
A LIARLA!!