Páginas

viernes, 29 de febrero de 2008

Curso de bots (II)

Hoy haremos nuestro primer bot desde cero. La vez anterior utilizamos un script para poner interwikis que ya estaba hecho. Nuestro bot no tendrá utilidad alguna más allá de enseñarnos las funciones básicas para el control de páginas de Wikipedia: capturar el contenido, hacer alguna operación con él, y subir el contenido nuevo al servidor.

Hay que tener en cuenta que cualquier script que programemos deberá almacenarse en el directorio donde tengamos descomprimido pywikipediabot, en la primera entrega dijimos c:\bots.

Si abres el archivo wikipedia.py con el Notapad++ verás que en la parte de arriba contiene una serie de instrucciones. El primer bloque son funciones que pueden aplicarse a objetos "page" (página). El segundo bloque contiene funciones para los objetos "site" (sitio). Ambos objetos dependen uno de otro, toda página (o artículo) está en un sitio (proyecto de Wikimedia).

Si queremos trabajar con el artículo "Isaac Newton" debemos crear un objeto "page" pasándole el proyecto (Wikipedia en español) y el nombre del artículo (Isaac Newton). Esto se hace de la siguiente forma:
mipagina = wikipedia.Page(wikipedia.Site("es", "wikipedia"), u"Isaac Newton")
Asignamos a la variable mipagina el objeto creado con las características que ya hemos descrito. Ahora, supuestamente podemos hacer cualquier cosa con mipagina, desde bajarnos el contenido del artículo al que apunta, hasta trasladarlo.

Para que funcione la línea que he puesto antes, deberás incluir al principio de nuestro script lo siguiente:
import wikipedia
Lo que hace es importar la libreria wikipedia.py, ya que es donde se encuentrar las funciones Page y Site que hemos usado.

Esto de momento no hará nada, si lo ejecutas desde una ventana o shell lo podrás comprobar. El script se inicia, genera el objeto mipagina y acaba. No muestra nada. Completémoslo un poco.

Añade la línea wikipedia.output(mipagina.get()) al final de tu script y vuelve a ejecutarlo (sino recuerdas como ejecutar los scripts, lee la primera parte de este tutorial).
import wikipedia
mipagina = wikipedia.Page(wikipedia.Site("es", "wikipedia"), u"Isaac Newton")
wikipedia.output(mipagina.get())

¿Intuyes que va a hacer este programa? Mostrará el contenido del objeto mipagina en tu pantalla, esto es el contenido del artículo "Isaac Newton", con sus enlaces [[ ]] sin procesar, etc. Si el artículo es largo, como posiblemente así sea, veras un montón de líneas pasando muy rápido.

Hemos conseguido bajarnos el texto del artículo con la función get(). ¿Y si quisieramos modificar el artículo? Usaríamos la función put(). Como veis todo esto consiste en tener las funciones necesarias a mano y aplicarlas sobre el objeto mipagina.

Si quisieramos poner "Isaac Newton es el mejor científico de la historia" nuestro código se mostraría así:
import wikipedia
mipagina = wikipedia.Page(wikipedia.Site("es", "wikipedia"), u"Isaac Newton")
mipagina.put(u"Isaac Newton es el mejor científico de la historia", u"Estoy modificando el artículo de Newton")

La función put() recibe dos parámetros del tipo string o cadena. El primero de ellos es el contenido que subiremos al artículo, el segundo es el resúmen de edición.

Por favor, no ejecutes este script, es para que veais como se hace, no quiero que el historial de "Isaac Newton" se llene de ediciones de prueba. Para eso está la Zona de pruebas. Modifica tu script para que apunte a la Zona de pruebas, y entonces ejecútalo. ¿Cómo se hace esto? Cambiando el nombre de la página:
import wikipedia
mipagina = wikipedia.Page(wikipedia.Site("es", "wikipedia"), u"Wikipedia:Zona de pruebas")
mipagina.put(u"Estoy modificando la Zona de pruebas", u"Esto es una prueba")

Ahora sí, ejecútalo y ve al historial de la ZP y allí verás la edición de tu bot.

¿Y si resulta que queremos añadir texto al final de la página, sin destruir lo que ya hay escrito? Es muy fácil, tan solo hay que combinar ambas funciones put() y get():
import wikipedia
mipagina = wikipedia.Page(wikipedia.Site("es", "wikipedia"), u"Wikipedia:Zona de pruebas")
mipagina.put(u"%s\nEstoy modificando la Zona de pruebas" % mipagina.get(), u"Esto es una prueba")

¿Estás hecho un lío? Sólo hemos insertado un parámetro de formato en la cadena entre comillas, esto es %s y sirve para insertar en esa posición otra cadena. Como bien habrás adivinado, esta cadena es el contenido de la Zona de pruebas que le pasamos con mipagina.get(). Haciendo esto no borraremos el contenido de la Zona de pruebas, sino que estaremos añadiendo la frase "Estoy modificando la Zona de pruebas" al final de la página. El símbolo "\n" se utiliza para insertar una newline (nueva línea).

Ahora como recomendación, es posible que queramos modificar varias páginas, luego necesitaremos llamar varias veces a la función wikipedia.Page() para crear un objeto por cada página. Podemos simplificar el código insertando una línea al comienzo de nuestro script, tras la zona de importaciones.
import wikipedia
misitio = wikipedia.Site("es", "wikipedia")

mipagina = wikipedia.Page(misitio, u"Isaac Newton")
mipagina.put(u"%s\nLa línea sale al final" % mipagina.get(), u"Esto es una prueba")

mipagina = wikipedia.Page(misitio, u"Albert Einstein")
mipagina.put(u"Esta línea sale al principio\n%s" % mipagina.get(), u"Esto es una prueba")

Creando el objeto misitio nos ahorramos reescribir el tedioso texto wikipedia.Site("es", "wikipedia") una y otra vez y evitamos errores. Supongo que habrás intuido que cambiando "es" por "fr" o "en", estaremos editando Wikipedia en francés y en inglés respectivamente. Aunque tu bot necesitará estar registrado en ellas.

Como final, decir que leas la documentación de el fichero wikipedia.py, algunas muy interesantes son las siguientes:
isRedirectPage (*) : True if the page is a redirect, false otherwise
isEmpty (*) : True if the page has 4 characters or less content, not
counting interwiki and category links
interwiki (*) : The interwiki links from the page (list of Pages)
categories (*) : The categories the page is in (list of Pages)
linkedPages (*) : The normal pages linked from the page (list of Pages)
imagelinks (*) : The pictures on the page (list of ImagePages)
isDisambig (*) : True if the page is a disambiguation page

Y recuerda, todas las pruebas en la Zona de pruebas.

Licencia

Unless stated otherwise, the text of the blog posts is published under this Creative Commons license.
A menos que se indique otra cosa, el texto de las entradas del blog se publica bajo esta licencia Creative Commons.
Licencia de Creative Commons