Extraer enlaces de una página web
Hace algunas semanas hablábamos de Publicar en Twitter las entradas de este sitio usando Python y prometíamos hacer lo mismo con Facebook.
Echando un vistazo al API de Facebook y haciendo algunas pruebas me encontré con que no podía publicar enlaces con su texto (Facebook los transforma para que podamos pinchar en ellos, pero no permite -o no encontré la forma- que los pongamos con su texto y esas cosas). Por otro lado, quería experimentar con la posibilidad de publicar las entradas de esta bitácora completas allí; Facebook no favorece que introduzcamos textos largos porque nos muestra un trocito y permite abrir ‘el resto’.
Siempre me ha llamado la atención la ‘netiqueta’ de algunas listas de correo donde suele ponerse al lado del texto de los enlaces un número y al final del mensaje la lista de esos enlaces, cada uno asociado al número correspondiente.
Esto fue lo que decidí hacer para publicar en la página de Facebook de fernand0.github.io (y otras, claro). El programa que traemos hoy hace justamente eso, como paso previo a la publicación en la página de Facebook (y, tal vez, ¿para poder enviar las entradas por correo a los interesados?).
El programa puede verse en rssToLinks.py (apuntamos, como siempre, la versión actual por si hubiera cambios en algún momento).
Algunas formas de extraer los enlaces serían: buscarlos con expresiones regulares, o también con algún parser de HTML (en el Blogómetro hace años utilizábamos el Simple SGML parser. Buscando un poco encontré el proyecto Beautiful Soup que presume de ser una manera rápida de recorrer el contenido de una página web y decidí darle una oportunidad.
Para utilizarlo incluímos los módulos necesarios. Para obtener el contenido utilizamos la fuente RSS, así que también necesitaremos feedparser
:
Leemos la fuente RSS y vamos recorriendo las entradas:
Y empieza la ‘magia’ de Beautiful Soup
:
Esto es, le pasamos los datos al analizador, y lanzamos la pregunta de lo que queremos extraer. En este caso tenemos una entrada en el summary
y queremos obtener los enlaces (etiqueta a
) para la entrada que ocupa la posición i
.
Nos devolverá una lista de elementos html que incluyen dicha etiqueta.
En algunas entradas ponemos imágenes, que no queremos que aparezcan en el texto, así que utilizamos isinstance
para comprobar si dentro del contenido del enlace hay otra etiqueta para evitarla (¿es posible que encontremos algún caso más adelante que sea problemático?). Recorremos la lista de enlaces (que vienen con las etiquetas y todo, claro). Ademas utilizamos el contador j
para ir asociándoles números a los sucesivos enlaces (en el HTML original, todavía no lo hemos eliminado):
El contenido del enlace (ahora que ya sabemos que no es una etiqueta HTML) estará en link.contents[0]
(puede haber más contenido, nuestros enlaces suelen ser ‘sencillos’).
El enlace está en link['href']
.
Ahora necesitamos el texto del HTML:
En algunos casos el texto puede tener muchos saltos de línea, espacios, … Se podrían eliminar. Nuestras entradas suelen estar bien estructuradas y no aparece ese problema.
Ahora, si había algún enlace (¿publicaremos alguna vez una entrada sin ningún enlace?), lo añadimos al final: