logo El diario de Pepe Molina (Caricatos)

yo

Hemos tenido un pequeño problema con la generación de nuestro "sitemap.xml" debido a que ha crecido bastante el contenido de esta página, por lo que hemos decidido revisarlo minuciosamente.


Última caricatura

IV Asamblea de la AEC: IV Asamblea General de la Asociación Española de Caricaturistas

IV Asamblea de la AEC

RSS de las imágenes: rss


La Cita

Experiencia es el nombre que damos a nuestras equivocaciones

Óscar Wilde, escritor irlandés (1854-1900).


En esta zona están las páginas personales del autor.


Mis clientes ahora también son mis amigos (aunque les cobre).


En Mis amigos Informáticos hay una pequeña colección de páginas de colegas webmasters..


En Mis amigos artistas podemos encontrar artistas de cualquier índole (dibujantes, pintores, escritores...)


Las recomendaciones que proponemos son de índole variada.


Aquí un cajón de sastre de enlaces.


Nos referencian desde sitios de toda índole.


Puede contribuir a mantener esta página con su donativo.


botón pay-pal

Este diario: sitemap.xml

emoticón de Caricatos Publicado el día 17 de octubre de 2012
id=98; categorías: Así se hizo, Vicisitudes de un Webmaster, Globalización, Programación, Experiencias SEO

Hemos tenido un pequeño problema con la generación de nuestro "sitemap.xml" debido a que ha crecido bastante el contenido de esta página, por lo que hemos decidido revisarlo minuciosamente.

En concreto, tan solo obteníamos unas pocas más de cien entradas, así que lo estamos re-implementando.

Los enlaces

Estamos interesados en que nuestras enlaces se generen correctamente así que hemos revisado que no exista ningún error en su localización.

Hemos descubierto algunos enlaces, sobre todo de imágenes que estaban mal referenciadas, así que decidimos hacer una búsqueda generalizada de enlaces, sobre todo descubrir los enlaces internos y eliminar la ruta absoluta de los mismos. Para ello hemos acudido a nuestro buscador interno (sección "Extras"), seleccionamos todas las tablas y en el campo de búsqueda insertando el nombre de nuestro dominio, obteniendo el listado de páginas que en su contenido se encuentra: pulse para ver ese resultado.

Revisando las páginas obtenidas en nuestra búsqueda, descubrimos que son casos con recortes de imágenes, y nuestro sistema necesita esa ruta completa para su funcionamiento, así que decidimos realizar las búsquedas algo más complejas, añadiendo al principio de la cadena a buscar los atributos donde va el nombre del dominio (href=", src="); chequeando también las mismas cadenas pero con comillas simples.

Las imágenes

La referencia de imágenes en el sitemap puede hacerse simplemente con su URL (ubicación), o adjuntando más información como un título o una descripción: Sitemaps de imágenes.

Revisando nuestro Listado de imágenes se nos ha ocurrido que podríamos aportar un título (nombre -> image:title) y una descripción (Resúmen -> image:caption). Para obtener esos datos desde la tabla de imágenes implementamos este código:

// Declaramos el array images para guardar información de nuestra tabla.
$images = array();

$sql = "select id, titulo, descripcion from $tabla_imagenes";
$res = @mysql_query($sql);
while ($dato = mysql_fetch_array($res))    {
	$id = $dato["id"];
	$titulo = $dato["titulo"];
	preg_match('/\[rss\](.*?)\[\/rss\]/is', $dato["descripcion"], $des);
	$info = preg_replace(array('/\<(.*?)\>/','/\"/'), '', $des[1]);
	$images[$id] = array("titulo" => $titulo, "info" => $info);
}

Ahora debemos buscar en los contenidos de las páginas que referenciamos en nuestro sitemap las imágenes y en el caso de que sean de nuestra tabla de imágenes, rescatar esa información adicional que hemos reseñado. Al tratarse de un mismo código para todos los textos, hemos implementado una función:

function sacaImagenes($texto)	{
	global $images, $diario_ruta;
	preg_match_all('/\<img src=\"(.*?)\"/is', $texto, $_imagen);
	$imgs = array();
	for ($i = 0, $total=count($_imagen[1]); $i < $total; $i++)
	if (substr($_imagen[1][$i], 0, 7) != "http://")	{
		$_src = $_imagen[1][$i];
		$_ids = substr($_src, 0, 17);
		$_id = false;
		if ($_ids == "diario.imagen.php")	{
			preg_match("/id=(\d*)/is", $_src, $__id);
			if (array_key_exists($__id[1], $images))	$_id = $__id[1];
		};
		if ($_id != false)	{
			$_titulo = $images[$_id]["titulo"];
			$_info = $images[$_id]["info"];
			array_push($imgs, array("loc" => "$diario_ruta/$_src", "title" => $_titulo, "caption" => $_info));
		}
		else	{
			array_push($imgs, array("loc" => "$diario_ruta/$_src"));
		}
	}
	return $imgs;
}

Con esa función obtenemos un array con los datos de las imágenes encontradas y que pertenecen al dominio por tener una ruta relativa.

Ahora nos queda mostrar las imágenes:

//$item es el objeto con los datos de una entrada del sitemap
//$item["images"] es el array de imágenes asociado al "$item"
while (count($item["images"]) > 0)	{
	$imagenes = array_pop($item["images"]);
	$lista .= "\n\t<image:image>";
	foreach($imagenes as $itemImage => $itemsito)
		$lista .= "\n\t\t<image:$itemImage><![CDATA[".$itemsito."]]></image:$itemImage>";
	$lista .= "\n\t</image:image>";
}

La experiencia de adaptar nuestro sitemap para referenciar nuestras imágenes nos ha servido para plantearnos futuros retos que en breve iremos comentando.

Prioridades

A pesar de que el valor "priority" de las entradas del sitemap no es relevante, pensamos que si podemos ofrecer mayor información de nuestro sitio será mejor valorado por los buscadores, así que nos atrevimos a implementar un sistema que genere un valor coherente para ese atributo.

Teniendo como base que los valores admitidos están entre el cero (0) y el uno (1), creemos oportuno darle valor "1.0" a la página principal. Las demás páginas tendrán como mínimo el valor "0.5", y dependerá de las visitas que hay registradas; por último dependiendo del tipo de página le daremos una prioridad mayor o menor. Con el código que mostramos a continuación apreciaremos esa discriminación:

$datosPrioridades = array(
	"apunte" => array("tope" => 4, "min" => false, "max" => false),
	"archivos" => array("tope" => 2, "min" => false, "max" => false),
	"imagen" => array("tope" => 4, "min" => false, "max" => false),
	"categoria" => array("tope" => 3, "min" => false, "max" => false),
	"etiqueta" => array("tope" => 3, "min" => false, "max" => false),
	"extra" => array("tope" => 3, "min" => false, "max" => false),
	"pagina" => array("tope" => 4.5, "min" => false, "max" => false)
);

Los tipos de páginas que tenemos en el sitemap son como puede apreciarse: apuntes, archivos, imágenes, categorías, etiquetas, extras y páginas. El valor que etiquetamos como tope es el máximo que sumaremos al "0.5" mínimo que ya hemos comentado, y ese tope coincidirá con el número máximo de visitas correspondientes a cada tipo (dividido por diez)... ¡Sí, sí!, todo un galimatías, por eso nos fiaremos que se entienda con el código:

function prioridad($tipo, $cual)	{
	global $datosPrioridades, $contadores;
	$yo = $contadores["$tipo.$cual"];
	$tope = $datosPrioridades[$tipo]["tope"];
	$min = $datosPrioridades[$tipo]["min"];
	$max = $datosPrioridades[$tipo]["max"];
	return number_format(0.5 + ($tope * (($yo * $min) / ($max * $min)) / 10), 2);
}

Este código nos devuelve un número entre "0.5" y un valor máximo igual al tope dividido 10... o sea entre 0.5 y 0.9 en los apuntes; entre 0.5 y 0.95 en el tipo "página", etc.

Nos falta explicar de donde sale esa variable "$yo" de nuestro código, que evidentemente es un valor numérico obtenido desde un array, en concreto el número de veces que fue visitada la página:

$contadores = array();
$sql = "select pagina, cuenta from $tabla_contadores order by pagina";
$res = @mysql_query($sql);
while ($dato = mysql_fetch_array($res))	{
	$pag = $dato["pagina"];
	$cuenta = $dato["cuenta"];
	$contadores[$pag] = $cuenta;
	list($tipo) = explode(".", $pag);
	if (!$datosPrioridades[$tipo]["min"])	{
		$datosPrioridades[$tipo]["min"] = $cuenta;
	}
	elseif ($cuenta < $datosPrioridades[$tipo]["min"])	{
		$datosPrioridades[$tipo]["min"] = $cuenta;
	}
	if (!$datosPrioridades[$tipo]["max"])	{
		$datosPrioridades[$tipo]["max"] = $cuenta;
	}
	elseif ($cuenta > $datosPrioridades[$tipo]["max"])	{
		$datosPrioridades[$tipo]["max"] = $cuenta;
	}
}

El código también nos muestra como obtenemos el valor máximo y mínimo de cada tipo de página.

Generando nuestro sitemap.xml

Empezaremos con la cabecera XML:

// La cabecera header se ha usado durante las pruebas...
//header("Content-type: text/xml");
$cabeza =<<< cabecera
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="sitemap.xsl" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

cabecera;
$ahora = date("Y-m-d"); 

$lista = "";
$listados = array();

$listados["index"] = array("link" => $diario, "fecha" => $ahora, "images" => array(array("loc" => "$diario_ruta/caricatos.ico", "title" => "icono de $diario_titulo", "caption" => "Icono de mi caricatura")), "pri" => "1.0");

Vemos que a la vez que generamos la cabecera, también abrimos la etiqueta "urlset", dejando el contenido en la variable "$cabeza". También tenemos la variable "$ahora" con la fecha actual en formato válido para sitemaps. Un array llamado "$listados" con un elemento "index" que será la primera url del sitemap, y que representará la raíz del mismo. Antes de detenernos en el sentido de la variable "$lista" veremos el tratamiento de un tipo de página: "los apuntes".

$sql = "select id, titulo, apunte, fecha from $tabla_apuntes where activo > 0 order by fecha desc"; 
$res = @mysql_query($sql); 

while ($dato = mysql_fetch_array($res))    {
	$id = $dato["id"];
	$titulo = $dato["titulo"];
	$link = $diario."?titulo=".urlencode($titulo);
	$fecha = substr($dato["fecha"], 0, 10);
	$imgs = sacaImagenes($dato["apunte"]);
	$listados["apunte.$id"] = array("link" => $link, "fecha" => $fecha, "images" => $imgs, "pri" => prioridad("apunte", $id));
	list($aaaa, $mm) = explode("-", $fecha);
	$cadena_archivos = $mes[$mm]." $aaaa";
	if (!isset($archivos[$cadena_archivos]))	$archivos[$cadena_archivos] = array();
}

Omitiremos explicar las tres últimas líneas del código ya que solo sirven para obtener los datos de las secciones "archivos", pero puede notarse que se van generando elementos del array "$listados" con los datos que usaremos en cada etiqueta "url" de nuestro sitemap.

El siguiente código es concretamente el que genera todas las "url"s:

foreach ($listados as $dato => $item)	{
	$lista .= "<url>\n\t";
	$lista .= "<loc>".$item["link"]."</loc>";
	if (isset($item["fecha"]))
		$lista .= "\n\t<lastmod>".$item["fecha"]."</lastmod>";
	$lista .= "\n\t<changefreq>never</changefreq>";
	$lista .= "\n\t<priority>".$item["pri"]."</priority>";
	while (count($item["images"]) > 0)	{
		$imagenes = array_pop($item["images"]);
		$lista .= "\n\t<image:image>";
		foreach($imagenes as $itemImagen => $imagen)
			$lista .= "\n\t\t<image:$itemImagen>$imagen</image:$itemImagen>";
		$lista .= "\n\t</image:image>";
	}
	$lista .= "\n</url>\n";
}

Para terminar cerramos esa etiqueta "urlset" y volcamos el sitemap:

$sitemap = "$cabeza\n$lista\n</urlset>\n";
file_put_contents("sitemap.xml", $sitemap);

Nos falta...

La prueba de fuego

Es hora de generar el sitemap y probarlo en las herramientas para webmaster de google...

He de reconocer que el primer intento fue un fracaso por los parámetros que llevaban algunas imágenes, no obstante se ha solucionado sencillamente ya que solo debía cambiar los elementos "&" por su entidad "&amp;". Con el siguiente código:

$_src = preg_replace('/(&amp;|&)/', '&amp;', $_imagen[1][$i]);
//$_src = str_replace("&amp;amp;", "&amp;", str_replace("&", "&amp;", $_imagen[1][$i]));

Tenemos más para contar, pero lo dejaremos para más adelante...

Zona de comentarios

Este apunte aún no tiene comentarios.

Evaluación

Valoración de esta página: (apunte.98) valor

Valoración evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar evaluar

Respuesta: Zona de mensajes (proceso de evaluación)

Historial de navegación

Esta página ha sido visitada en 3376 ocasiones


Disponemos de rss sindicar

Y del Mapa del sitio, además del sitemap.xml.


Aquí podemos encontrar los apuntes más visitados.

"Top 10" reemplaza a la sección Últimos apuntes.


Una buena forma de buscar un apunte es a partir de su categoría.


También es posible buscar apuntes por medio de las etiquetas (tags).


Hemos decidido poner al alcance de todos algunos comodines.

Adjuntamos una versión reducida del "buscador interno" que vemos en la lista anterior:

Buscar en apuntes

También estamos recopilando antiguas páginas del sitio.


Desde este recuadro se puede hacer una búsqueda cronológica.


Se puede crear una postal nueva desde el enlace del sector "Otras páginas del dominio", o editar la que sale en el recuadro, pulsando sobre ella..

http://www.pepemolina.com/postales/Fondos/FONDO005.gif
http://www.pepemolina.com/postales/Musicales/Imagen1.gif
http://www.pepemolina.com/postales/Musicales/Imagen2.gif
http://www.pepemolina.com/postales/Musicales/Imagen3.gif
http://www.pepemolina.com/postales/Musicales/Imagen4.gif
http://www.pepemolina.com/postales/Musicales/Imagen5.gif
http://www.pepemolina.com/postales/Musicales/Imagen6.gif
http://www.pepemolina.com/postales/Musicales/Imagen7.gif
Postal Digital
Postal Digital
enlace a la postal
Copyright © 2002-2018 www.pepemolina.com
RSS rss | Ver Mapa del sitio