La Gaceta de Linux ... ¡ haciendo a Linux un poco más divertido !

RSS y lectores de Feed

Por Jimmy O'Regan

Traducción al español por José Manuel Pérez
el día 4 de Abril de 2005, para La Gaceta de Linux

Los RSS, lectores de feed y agregadores de noticias son un tema candente en la actualidad. Dada la enorme cantidad de noticias disponibles en la red, tiene sentido el intentar ser capaz de leer todas las noticias en las que uno está interesado, sin tener que comprobar más de una docena de sitios Web. Con un buen lector de feed, puedes subscribirte a tus sitios de noticias favoritos y hacer que el software encuentre las noticias por ti, incluso en sitios a los que no entrarías tan a menudo como querrías.

RSS es un componente de la Web Semántica - y el único elemento disfrutable actualmente de uso común. RSS no es el único formato disponible para obtener feeds de noticias, e incluso el nombre "RSS" describe dos formatos diferentes. Digo nombre en vez de acrónimo porque "RSS" se ha usado para denotar tanto a "RDF Site Summary" (Resumen de Sitio RDF), "Rich Site Summary" (Resumen de Sitio Rico), y "Syndication Really Simple" (Distribución Realmente Sencilla), y por esto, se ve más como un nombre, para evitar confusión.

Para aquéllos a los que les interese, RSS fue en un principio RDF Site Summary, y mantuvo una gran semejanza con RSS 1.0. RDF fue eliminado para la primera versión pública, y fue renombrado a Rich Site Summary, y Dave Winer (autor de RSS 0.92 y RSS 2.0) lo apodó como Really Simple Syndication.

Antes de RSS

Antes de que RSS fuese creado, varios sitios, como Slashdot, usaron archivos personalizados de texto para definir sus titulares. De esta manera otros sitios de noticias podrían hacer uso de ellos.

Una línea para información, otra línea para la fecha.
%%
<A HREF="http://linux.ie/newsitem.php?n=540">Artículo sobre PAM</A>
23-July-2004 9:19
%%
<A HREF="http://linux.ie/newsitem.php?n=483">Artículos para la guía para principiantes en Linux</A>
4-July-2004 2:55
Muestra del backend de texto de Linux.ie.

Cuando la versión 4 de los navegadores fue publicada, incluyeron sus propios mecanismos para dar soporte al "contenido push" (secciones de sitios Web que fueron diseñadas para que la gente se suscribiera). Si el usuario se subscribía al canal, su navegador leía la descripción del canal y periódicamente comprobaba ese sitio para llevar a cabo actualizaciones, descargando las partes relevantes.

Netscape usó una barra lateral basada en HTML (que aún está presente en Mozilla, etc.), pero en Microsoft crearon el "Channel Description Format" (Formato de Descripción de Canal), que enviaron al W3C. (Muestra). El contenido push no tuvo éxito en el momento, pero el posterior trabajo en RSS lo ha logrado, aunque no para el contenido push. (Aunque Dave Winer añadió el elemento <enclosure> al RSS 0.92 para permitir el push en RSS).

RSS/Atom

La versión original de RSS fue la 0.90, diseñada por Netscape para ser usada en su portal "My Netscape". Se basó originalmente en RDF, pero según la línea cronológica de RSS, el personal de marketing de Netscape hizo que el proyecto fuera echado por tierra. Netscape desarrolló más tarde el formato, para resultar más cercano al script XML de noticias de Dave Winer (Muestra).

Winer mantuvo la especificación RSS, pero mientras tanto, el W3C lanzó al mercado su propia especificación RSS, basada en la idea original de tener un formato basado en RDF para la distribución. Esto eliminó la mayor parte de las etiquetas específicas de RSS, y usó el esquema RDF para ofrecer etiquetas análogas. Desde que el W3C decidiese llamar a este RSS 1.0, Winer nombraría a su versión actualizada RSS 2.0.

A raíz de esta confusión, un grupo de trabajo de IETF (Grupo de trabajo especial de ingeniería de internet) comenzó a producir un formato alternativo, llamado Atom (formalmente Echo), que, desafortunadamente, sólo sirvió para sumarse a la confusión.

RDF 2.0 es compatible hacia atrás con RSS 0.92, el cual es, a su vez, compatible hacia atrás con RSS 0.91. La diferencia principal entre RSS 2.0 y RSS 1.0 es que RSS 1.0 elimina todos los términos del esquema RSS que están disponibles en otro esquema (en lugar del elemento <title>, por ejemplo, podrías incluir una referencia al esquema Dublin Core, y usar <dc:title> en su lugar). RSS 2.0 tiene extensiones para poder trabajar con esquema RDF, como, si no me falla la memoria, también puede hacer Atom.

También hay disponibles sitios Web que convierten los feeds al formato que desees, como por ejemplo 2rss.com y RSS2Atom. A la Gaceta de Linux se puede acceder como un feed de Atom desde http://www.tnl.net/channels/rss2atom/http://linuxgazette.net/lg.rss.

Lectores de Feed

Liferea

Liferea en acción

Liferea es mi lector de feed favorito. Ofrece una interfaz gráfica similar a la de la mayor parte de los lectores populares de Windows, soporta varios formatos (¡incluso CDF!), y se integra en la bandeja del sistema. Cuando está minimizado en la bandeja, es muy discreto. Cuando llegan nuevas noticias, se colorea el icono; si no, es agrisado (aunque la versión que estoy utilizando tiene un problema con el feed de Atom de mi BlogSpot - compruébalo si te pica la curiosidad).

Snownews

Snownews

Snownews Snownews es un lector de feed basado en ncurses para la consola. Maneja RSS 0.9x, 0.1 y 0.2, pero puede ser extendido con scripts para leer otros formatos. Snownews tiene una interfaz excelente, que recuera a Pine/Pico. Snownews comienza con una pantalla en blanco. Los diversos comandos están limitados a pulsaciones sencillas de teclas (que pueden ser configuradas editando .snownews/keybindings). Para agregar un feed, teclea 'a', e introduce el URL cuando te lo pida. Para abrir un artículo en lynx (o cualquier navegador que elijas para entrar en .snownews/browser), presiona 'o'.

Las versiones más recientes de Liferea y Snownews permiten usar la salida de otro programa como fuente de feed. RSSscrape, que trataré dentro de un momento, es una gran herramienta a utilizar con cualquiera de estos programas.

Devedge RSS Ticker

Ben me dirigió rumbo al Ticker RSS de Netscape Devedge. Éste es un ticker RSS muy sencillo, que fue creado como un ejemplo para un artículo de Devedge. Por defecto, sólo soporta 3 sitios de noticias - Devedge, CNet, y The New York Times. Hay tickers mejores disponibles para Mozilla.

URSS

URSS

URSS es otro ticker de noticias basado en Mozilla, originalmente basado en el ticker de Devedge. Te permite añadir tus propios feeds, y agrega un recuadro complementario que permite leer titulares y descripciones. Sin embargo, no lo uso mucho, ya que no es capaz de leer el feed de La Gaceta de Linux, aunque este tema quizás no tenga importancia cuando este artículo aparezca en los quioscos de periódicos, puesto que encontré código erróneo en los RSS que ya he arreglado.

Una mirada a varios feeds

RSS 0.9x

La Gaceta de Linux utiliza el formato RSS 0.91, el formato original diseñado por Netscape. Esto es un extracto de un tema del mes anterior:

<rss version="0.91">

<channel>
<title>Linux Gazette</title>
<link>http://linuxgazette.net</link>
<description>An e-zine dedicated to making Linux just a little bit more fun.
Published the first day of every month.</description>
<language>en</language>
<webMaster>(email omitted)</webMaster>
<image>
<title>Linux Gazette RSS</title>
<url>http://linuxgazette.net/gx/2004/newlogo-blank-100-gold2.jpg</url>
<link>http://www.linuxgazette.net/</link>
</image>

<issue>104</issue>
<month>July</month>
<year>2004</year>

<item>
<title>The Mailbag</title>
<link>http://linuxgazette.net/104/lg_mail.html</link>
<description></description>
</item>

</channel>
</rss>

Bastante directo, ¿no crees? Desde el número 105, hay algunos bits extra. La etiqueta <webMaster> ha sido añadida para complementar la etiqueta <managingEditor>, y la etiqueta <image> tiene como opcionales las etiquetas <height> y <width>:

<image>
<title>Linux Gazette RSS</title>
<url>http://linuxgazette.net/gx/2004/newlogo-blank-100-gold2.jpg</url>
<link>http://www.linuxgazette.net/</link>
<height>42</height>
<width>99</width>
</image>

Una etiqueta que habría sido muy práctica es <textinput>, que te permite buscar un sitio web desde tu lector de feed. Desafortunamente, como GL utiliza la búsqueda del sitio de Google, no podemos usarla, puesto que requeriría un parámetro extra que RSS no soporta.

Cogeremos esta fragmento de la URL de búsqueda de Google: http://www.google.com/search?q=test. Aquí tenemos cómo sería una entrada de texto para esa URL:

<textinput>
<title>Search</title>
<description>Search Google.</description>
<name>q</name>
<link>http://www.google.com/search</link>
</textinput>

Una cosa que ocurrte con el feed RSS de GL es que <issue>, <month> y <year> no son etiquetas válidas. Desde el próximo número, esta información estará en la descripción del canal - de todas formas antes no se utilizaba.

Nuestra <description> ahora es así:

<description>An e-zine dedicated to making Linux just a little
bit more fun.
Published the first day of every month.
&lt;br&gt;
Issue 105: August, 2004
</description>

Nota el uso de HTML "escapeado" - esto puede ser empleado en cualquier <description>.

RSS 0.92 y 2.0

RSS 0.92 es una versión extendida de Dave Winer del RSS 0.91. La principal diferencia entre RSS 0.91 y 0.92 es que varias etiquetas se convirtieron en opcionales, y el límite de 15 ítems por feed fue eliminado. Algunas etiquetas experimentales fueron añadidas, pero no son realmente útiles para la mayoría de la gente - aparte del elemento <enclosure> que ya he mencionado, está también el elemento <cloud>, que se usa para proporcionar un enlace a un servicio XML-RPC o SOAP, que es usado para decirle a los agregadores que el feed ha sido actualizado.

RSS 2.0 está desarrollado sobre RSS 0.92. I couldn't make out what the differences between RSS 2.0 and 0.92 were, though.

RSS 1.0

RSS 1.0 también es compatible hacia atrás con RSS 0.91, aunque en lugar de añadir nuevas etiquetas para soportar nuevos conceptos, puede ser referenciado un esquema diferente RDF. Slashdot, por ejemplo, tiene su esquema propio que representa la sección, departamento, el número de comentarios y el "hit parade".

La primera diferencia que notarás es que el elemento raíz es <rdf:RDF> en lugar de <rss>. Otra diferencia es que las etiquetas <channel>, <image> y <item> ahora tienen atributos rdf:about, y que las etiquetas <image> y <item> deben aparecer ahora fuera de la etiqueta <channel>, y deben tener etiquetas concordantes con rdf:resource dentro del elemento canal (esto también se aplica al elemento <textinput>).

Atom

Atom fue diseñado porque las versiones de RSS resultaban ser frustrantes. También es evidente que fue diseñado después de que los blogs se hicieran populares, mientras que RSS lo antecede. Los feeds de Atom, como es de esperar, son similares a los feeds RSS.

Aquí tenemos un ejemplo de un feed de Atom:

<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page
outlining rules you must respect.
http://www.livejournal.com/bots/  -->
<feed version='0.3' xmlns='http://purl.org/atom/ns#'>
<title mode='escaped'>Dung by any other name...</title>
<tagline mode='escaped'>jimregan</tagline>
<link rel='alternate' type='text/html'
href='http://www.livejournal.com/users/jimregan/' />
<modified>2004-07-26T01:12:32Z</modified>
<link rel='service.feed' type='application/x.atom+xml'
title='AtomAPI-enabled feed'
href='http://www.livejournal.com/interface/atomapi/jimregan/feed'/>
  <entry>
    <title mode='escaped'>Sample title</title>
    <id>urn:lj:livejournal.com:atom1:jimregan:4251</id>
    <link rel='alternate' type='text/html'
    href='http://www.livejournal.com/users/jimregan/4251.html' />
    <issued>2004-07-26T02:12:00</issued>
    <modified>2004-07-26T01:12:32Z</modified>
    <author>
      <name>jimregan</name>
    </author>
    <content type='text/html' mode='escaped'>A simple example.</content>
  </entry>
</feed>

Atom no es tan sencillo como RSS - incluso RSS 1.0, con RDF, es más fácil. Es también mucho más reciente que RSS, y no tan documentado, ni tan bien soportado. Es, sin embargo, el único tipo de feed soportado por Blogger, el sitio de Blogs de Google, así que podemos esperar un mayor soporte para ello.

Intenté llevar a cabo un creador de Atom para GL, para poder soportar los tres tipos de feeds, pero ninguno de los lectores de feed que instalé fueron capaces de mostrar nada útil de mi feed. Si no te lo crees, lo he incluido - puedes comprobarlo usando FeedValidator.org.

Screen Scrapers (Raspadores de pantalla)

Un scraper es un programa que chequea un sitio web buscando cierta información. En ese contexto, queremos coger un sitio que no disponga de feed, y generar uno, porque a todos nos chifla la idea de los lectores de feed actualmente, siendo tan "ultra-hip" como somos, ¿no es cierto? - pero también se usan para comprobar precios, detalles de vuelos, subastas, etcétera. Hay varias compañías que basan su negocio completamente en "raspar" otros sitios.

Así que, básicamente, un screen scraper es un script que hurga en una página web, la recorre a través de una expresión regular o dos, y separa los resultados en el formato deseado.

Todavía soy novato en Perl, y ya que no quiero presionar demasiado a Ben, nuestro residente gurú de Perl, usaré RSSscraper, un proyecto que ofrece un marco de trabajo para scrapers, incluyendo la generación de código RSS, así que sólo tendrás que proporcionar la URL y la expresión regular (además, está escrito en Ruby, así que horrorizaré a Thomas por la pobre calidad de mi código (\o/) - mira esto para comprobar de qué estoy hablando.

Aquí está mi ejemplo, ligeramente formateado para que quede bien en la pantalla. (Versión texto).

class BenScanner < RSSscraper::AbstractScanner
	def initialize
		@url_string = 'http://okopnik.freeshell.org/blog/blog.cgi'
		@url_proper = 'http://okopnik.freeshell.org/blog/'
		@postsRE = /div class="HeadText"> \n\n([^<]*)\n\n
		<\/div>\n<\/td>\n<\/tr>\n\n<tr>\n
		<td bgcolor="#fdfded" class="UsualText" valign="middle">
		\n\n<br><b>([^<]*)<\/b><p>\n\n
		([^\]]*)\n\n<p>\[ <a href="([^\s\t\r\n\f]*)">
		([^<]*)<\/a>/m
	end

	def find_items
		require 'cgi'
		items = Array.new
		request_feed.scan(@postsRE).each{ |date, title, content, comments_link, comments|
                        items << { :title => title,
				   :description => "#{CGI::escapeHTML(content)}",
                                   :comments_link => @url_proper+comments_link,
				   :comments => @url_proper+comments_link
                                 }
		}
		items
	end
end

class Ben < RSSscraper::AbstractScraper

	def scanner
		BenScanner.new
	end

	def description
	{
	        :link => 'http://okopnik.freeshell.org/blog/blog.cgi',
		:title => 'The Bay of Tranquility',
		:description => 'Ben Okopnik\'s blog.',
		:language => 'en-us',
		:generator => generator_string
	}	
	end

end

Fijándote en las partes en negrita, probablemente pienses que necesitas cambiar el nombre de la clase principal, y de la clase scanner. El archivo debe ser nombrado como [Foo].scraper.rb, y estas clases entonces serán nombradas [Foo] y [Foo]Scanner.

Después de eso los ítems en description son bastante obvios. @url_string es la URL del sitio que queremos analizar gramaticalmente; @url_proper sólo es requerido en este caso porque el enlace de comentarios no es una cadena añadida al enlace de blog, como sí lo es en la mayoría de los casos. @postsRE es la expresión regular, y date, etc. son los elementos que queremos extraer.

La expresión regular es la parte más complicada, e incluso eso, no es demasiado complicado - tan sólo recuerda que las partes que deseas extraer van entre paréntesis.

Cuando hayas rellenado los huecos, lo sitúas en tu carpeta de scrapers, y lo ejecutas como: scrape.rb [Foo].

Generando RSS

Bueno... mentí sobre querer escatimar. Voy a mostrar un ejemplo sencillo de un generador RSS en Perl.

CPAN tiene un módulo fantástico para generar RSS (tanto en 1.0 como 0.9x), llamado XML::RSS.

Echemos un vistazo a una muestra para generar RSS 0.91 (Texto, muestra de salida).

#!/usr/bin/perl -w

use strict;
use XML::RSS;

my $rss = new XML::RSS (version => '0.91');
$rss->channel(title          => 'Linux Gazette',
              link           => 'http://linuxgazette.net',
              language       => 'en',
              description    => 'An e-zine dedicated to making Linux just a little bit more fun.
Published the first day of every month.
<br>Issue 105: August, 2004',
              copyright      => 'Copyright (c) 1996-2004 the Editors of Linux Gazette',
              managingEditor => 'email@here.com',
              webMaster      => 'email@here.com');

$rss->image(title  => 'Linux Gazette',
            url    => 'http://linuxgazette.net/gx/2004/newlogo-blank-100-gold2.jpg',
            link   => 'http://www.linuxgazette.net/',
            width  => '99',
            height => '42');
              
$rss->add_item(title       => 'Securing a New Linux Installation',
               link        => 'http://linuxgazette.net/105/odonovan.html',
               description => 'By Barry O\'Donovan');

$rss->save("perl-test.rss");

Para crear un feed RSS 1.0, podríamos simplemente tomar el ejemplo, y cambiar la versión a 1.0 (quedando así), pero con RSS 1.0 podemos añadir un esquema diferente. XML::RSS usa Dublin Core y taxonomías dmoz por defecto (puedes, por supuesto, añadir otros fácilmente, pero no voy a explicar eso).

(Texto y muestra de salida)

#!/usr/bin/perl -w

use strict;
use XML::RSS;

my $rss = new XML::RSS (version => '1.0');
$rss->channel(title          => 'Linux Gazette',
              link           => 'http://linuxgazette.net',
              description    => 'An e-zine dedicated to making Linux just a little bit more fun.
Published the first day of every month.
<br>Issue 105: August, 2004',
              #XML::RSS will do the dc stuff for us, but just to illustrate...
              dc => {rights    => 'Copyright (c) 1996-2004 the Editors of Linux Gazette',
                     creator   => 'email@here.com',
                     language  => 'en',},
              taxo => ['http://dmoz.org/Computers/Software/Operating_Systems/Linux/']);

$rss->image(title  => 'Linux Gazette',
            url    => 'http://linuxgazette.net/gx/2004/newlogo-blank-100-gold2.jpg',
            link   => 'http://www.linuxgazette.net/',
            width  => '99',
            height => '42');
              
$rss->add_item(title       => 'Securing a New Linux Installation',
               link        => 'http://linuxgazette.net/105/odonovan.html',
               description => 'By Barry O\'Donovan');

$rss->save("perl-test.rss");

Y eso es todo. Espero que algunos de vosotros hayáis encontrado esto interesante, y sé por experiencia que puedo haber cometido errores. En ese caso, no dudéis en contactar conmigo. Cuidaos.

 


[BIO] Jimmy lleva usando ordenadores desde los siete años, cuando su padre le dejó un Amstrad PCW8256. Después de unos pocos flirteos breves con un Atari ST y versiones numerosas de DOS y Windows, Jimmy se introdujo en Linux en 1998 y no ha vuelto atrás.

Jimmy es padre de un tecnoadicto llamado Mark de siete años de edad. En su tiempo libre disfruta fuera de su círculo personal de Hell, trabajando en una fábrica. A Jimmy le gusta tocar la guitarra y editar la Wikipedia.

Copyright © 2004, Jimmy O'Regan. Publicado bajo los términos de la Open Publication License

Publicado en en Número 105 de Linux Gazette, Agosto de 2004