¿Cuántas veces has intentado crear un proceso que obtenga las urls del sitemap.xml de una página web? A continuación vamos a desarrollar una función en Python que nos permitirá extraer todas las urls almacenadas en un sitemap.xml.
Para comenzar, veamos ¿qué es un sitemap.xml? Según la página sitemap.org (página de referencia básica en este asunto):
Los Sitemaps son una forma fácil que tienen los webmasters para informar a los motores de búsqueda de las páginas que se pueden rastrear en sus sitios web. Un Sitemap, en su forma más sencilla, es un archivo XML que enumera las URL de un sitio junto con metadatos adicionales acerca de cada una de ellas.
O dicho de otra forma, es un listado con todas las urls accesibles de una página web, imagina las facilidades que proporciona el tener un sitemap para los motores de búsqueda, de ahí que luego ellos favorezcan las webs con este tipo de elementos.
Bueno, ya sabemos qué es un sitemap, pero ¿qué estructura tiene? Tal y como dice la definición de sitemap.org, este archivo no es más que un archivo XML con la siguiente estructura:
1: <?xml version="1.0" encoding="UTF-8"?>2: <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">3:4: <url>5: <loc>http://www.example.com/</loc>6: <lastmod>2005-01-01</lastmod>7: <changefreq>monthly</changefreq>8: <priority>0.8</priority>9: </url>10:11: </urlset>
Donde cada nodo <url> se corresponde directamente con una url de la web. Lo más importante del nodo <url> es el nodo hijo <loc>, del cual obtendremos la url a extraer.
Además de esta estructura, un sitemap puede emplearse como sitemap índice, es decir, un sitemap principal que contiene a otros sitemaps finales. La estructura de este índice es la siguiente:
1: <?xml version="1.0" encoding="UTF-8"?>2: <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">3:4: <sitemap>5: <loc>http://www.example.com/sitemap1.xml.gz</loc>6: <lastmod>2004-10-01T18:23:17+00:00</lastmod>7: </sitemap>8:9: <sitemap>10: <loc>http://www.example.com/sitemap2.xml.gz</loc>11: <lastmod>2005-01-01</lastmod>12: </sitemap>13:14: </sitemapindex>
De nuevo, observamos la existencia del nodo <loc>, que en este caso apunta a los sitemaps incluidos en el índice, en lugar de a las urls de la web.
Por tanto, para extraer las urls de un sitemap.xml, deberemos detectar si el sitemap a leer es un archivo de índice o no, cosa que haremos gracias al nodo principal del archivo XML, el cual será <sitemapindex> para archivos índice, y <urlset> para archivos sitemap finales.
A continuación se muestra el código en Python para la lectura de un archivo sitemap.xml, detectando si el archivo es un archivo índice o no. El resultado será un array con todas las urls detectadas.
Mencionar el uso del toolkit LXML para simplificar la lectura y manipulación del archivo XML.
1: import urllib2
2: from lxml import etree
3: from StringIO import StringIO4:5: def sitemap_reader(sitemap_url):
6: """7: Devuelve una lista con las urls incluidas en el sitemap de la url indicada8: """9: # Crea la lista que almacenará las urls10: urls = []11:12: # Variable que contiene el sitemap en formato xml13: xml = False14:15: # Lee el contenido del sitemap proporcionado16: response = urllib2.urlopen(sitemap_url)17: content = response.read()
18:19: # Comprueba si hay contenido que analizar20: if '' != content:
21: # Intenta generar el xml a partir del contenido extraído22: try:23: xml = etree.parse(StringIO(content))
24: except:25: # Error al procesar el sitemap.xml26: xml = False27:28: # Si se procesó correctamente el XML, procesar el sitemap29: if False != xml:
30: # Comprobar si el sitemap es un índice (nodo raíz = "sitemapindex")
31: if 'sitemapindex' == xml.getroot().xpath('local-name()'): # Sitemap index32: # Extrae todos los sitemaps incluidos en el índice (en el nodo "loc")
33: for sitemap_hijo in xml.xpath('//*[local-name() = "loc"]'):
34: # Procesa los sitemaps hijos de forma recursiva35: new_urls = sitemap_reader(sitemap_hijo.text)36: # Une todas las urls detectadas en el array final37: urls = urls + new_urls38: else: # Sitemap final
39: # Extrae las urls almacenadas en el sitemap y las almacena40: for url in xml.xpath('//*[local-name() = "loc"]'):
41: urls.append(url.text)42: # Devuelve las urls detectadas, pero elimina antes las urls duplicadas43: return list(set(urls))
44:45:46: # Modo de empleo47: urls = sitemap_reader('http://www.example.com/sitemap.xml')
Y vosotros, ¿tenéis un método para leer los sitemaps.xml?
Espero que os sea de ayuda en vuestros proyectos.
0 comentarios: (+add yours?)
Publicar un comentario