Diferencia entre revisiones de «Usuario:Lmorillas/modulo lenguajes de marcas/xml/xpath/scraping con xpath»

De WikiEducator
Saltar a: navegación, buscar
(Página creada con '{{subst:Curso_Python_DGA_2011/acceso_a_datos/contenidos}}')
 
 
(Una revisión intermedia por el mismo usuario no mostrado)
Línea 1: Línea 1:
{{subst:Curso_Python_DGA_2011/acceso_a_datos/contenidos}}
+
{{MiTitulo| Scraping con xpath}}
 +
 
 +
== Web scraping: la web como fuente de información ==
 +
<br />
 +
{{Conocimiento previo|
 +
La web se está transformando en una web de datos, pero muy poca información se sirve de forma estructurada y abierta:
 +
* http://www.zaragoza.es/ciudad/risp/
 +
* http://www.data.gov/
 +
* http://data.gov.uk/
 +
 
 +
=== Dificultades ===
 +
* Información poco o mal estructurada
 +
* Etiquetado no válido
 +
 
 +
=== Alternativas ===
 +
* Leer la información de la web y parsearla con herramientas de análisis textual (expresiones regulares, etc.)
 +
Some people, when confronted with a problem, think “I
 +
know, I’ll use regular expressions.” Now they have two
 +
problems.
 +
  – Jamie Zawinski
 +
<source lang="python">
 +
from urllib import urlopen
 +
URL = 'http://mipagina.com'
 +
doc = urlopen(URL).read()
 +
</source>
 +
* Usar parsers de html/xml. Estos parsers tiene que poder leer '''tagsoup''' porque se encontrarán con código no válido:
 +
** BeautifulSoup, lxml, '''amara'''.
 +
}}
 +
 
 +
 
 +
{{Actividad|
 +
Title=Nuestra herramienta: Amara|
 +
===Dónde===
 +
* http://wiki.xml3k.org/Amara ([http://wiki.xml3k.org/Amara/Tutorial Tutorial])
 +
=== ¿Cómo se usa? ===
 +
* Tiene dos interfaces:
 +
<ul><li>
 +
Una muy rápida y con una sintaxis más cercana al xml
 +
<source lang="python">
 +
import amara
 +
URL = '....'  # URL puede ser una url, una ruta de un fichero o una cadena de texto
 +
doc = amara.parse(URL)
 +
</source>
 +
</li><li>
 +
Otra más amigable y fácil de utilizar, que convierte el xml en objetos python.
 +
<source lang="python">
 +
from amara import bindery
 +
URL = '....' 
 +
doc = bindery.parse(URL)
 +
</source>
 +
<source lang="python">
 +
# si el html o xml puede no ser válido:
 +
from amara.bindery import html
 +
URL = '....' 
 +
doc = html.parse(URL)
 +
</source>
 +
</li></ul>
 +
==== Instalar ====
 +
Para instalar la última versión:
 +
$ sudo pip install http://files.akara.info/00-amara-latest.tar.bz2
 +
Es necesario tener instalado un compilador de C y la cabeceras de python (en debian/ubuntu hay que instalar '''python-dev'''
 +
}}
 +
 
 +
=== Ejemplos habituales de uso ===
 +
====Búsqueda por expresiones XPATH====
 +
{{Tip | Hay herramientas como [http://getfirebug.com/ firebug] que permite copiar el XPATH de un elemento.}}
 +
=====Búsqueda de las imágenes de un artículo=====
 +
<source lang="python">
 +
>>> from amara.bindery import html
 +
>>> URL = 'http://heraldo.es'
 +
>>> doc = html.parse(URL)
 +
>>> imagenes = doc.xml_select(u'//img') # las imágenes van en etiquetas img
 +
>>> len(imagenes)
 +
65
 +
>>> primera_imagen = imagenes[0]
 +
>>> print primera_imagen.xml_encode()
 +
<img src="/MODULOS/global/publico/interfaces/img/logo-Heraldo.png" alt="Últimas noticias de Aragón, Zaragoza, Huesca y Teruel del periódico digital Heraldo.es"/>
 +
>>> for im in imagenes:
 +
        print im.src
 +
/MODULOS/global/publico/interfaces/img/logo-Heraldo.png
 +
/uploads/imagenes/iconos/titulos/jmj.jpg
 +
/uploads/imagenes/rec70/_cuatrovientos6_011b2ad5.jpg
 +
...
 +
</source>
 +
 
 +
=====Búsqueda de las entradas de una revista=====
 +
Barrapunto publica sus entradas como
 +
<source lang="html4strict">
 +
<div class="article">
 +
<div class="generaltitle">
 +
<div class="title">
 +
<h3>
 +
<a href="//softlibre.barrapunto.com/">Software Libre</a>: Todo listo para la celebración de los 20 años de Linux
 +
 +
</h3>
 +
</div>
 +
</div>
 +
<div class="details">
 +
...
 +
</div>
 +
...
 +
</div>
 +
</source>
 +
Para extraer los nombres de los artículos de la primera página:
 +
 
 +
<source lang="python">
 +
>>> from amara.bindery import html
 +
>>> from amara.lib import U  # Extrae los nodos de texto de un fragmento
 +
>>> articulos = doc.xml_select(u'//div[@class="article"]')
 +
>>> len(articulos)
 +
15
 +
>>> for ar in articulos:
 +
print U(ar.div).strip()  # Navega por el nodo artículo.
 +
                                # Cuidado con los espacios en blanco y saltos
 +
 
 +
Software Libre: Todo listo para la celebración de los 20 años de Linux
 +
Publicado SmartOS, sistema operativo basado en Illumos
 +
Un dispositivo permite a los invidentes ver a través de su lengua
 +
El fin de la ley de Moore
 +
...
 +
</source>
 +
 
 +
'''Más ejemplos''' en http://wiki.xml3k.org/Amara/Recipes
 +
=====Expresiones XPATH útiles=====
 +
<source lang="python">
 +
# Nodo que contenga una cadena de texto:
 +
expresion = u'.//text()[contains(., "python")]'
 +
expresion = u'.//text()[contains(., "%s")]' % cadena.decode('utf-8')
 +
# Nodos o atributos que contengan una cadena:
 +
expresion = expr = u'.//@*[contains(., "%s")]'
 +
</source>
 +
 
 +
 
 +
====Inyección de marcado ====
 +
Se puede transformar un documento para añadirle o quitarle información.
 +
* En este ejemplo añadimos unos links a los nombre de los autores, detectados por expresiones regulares:
 +
https://github.com/zepheira/amara/blob/master/demo/inject_markup.py
 +
* En este proyecto hacemos un uso intensivo de inyección de marcado en páginas web: https://bitbucket.org/lmorillas/iaaa/

Última revisión de 10:53 6 feb 2012


Web scraping: la web como fuente de información



Icon preknowledge.gif

Conocimiento previo

La web se está transformando en una web de datos, pero muy poca información se sirve de forma estructurada y abierta:

Dificultades

  • Información poco o mal estructurada
  • Etiquetado no válido

Alternativas

  • Leer la información de la web y parsearla con herramientas de análisis textual (expresiones regulares, etc.)
Some people, when confronted with a problem, think “I
know, I’ll use regular expressions.” Now they have two
problems.
 – Jamie Zawinski
from urllib import urlopen
URL = 'http://mipagina.com'
doc = urlopen(URL).read()
  • Usar parsers de html/xml. Estos parsers tiene que poder leer tagsoup porque se encontrarán con código no válido:
    • BeautifulSoup, lxml, amara.





Icon activity.jpg

Nuestra herramienta: Amara

Dónde

¿Cómo se usa?

  • Tiene dos interfaces:
  • Una muy rápida y con una sintaxis más cercana al xml
    import amara
    URL = '....'  # URL puede ser una url, una ruta de un fichero o una cadena de texto
    doc = amara.parse(URL)
  • Otra más amigable y fácil de utilizar, que convierte el xml en objetos python.

    from amara import bindery
    URL = '....'  
    doc = bindery.parse(URL)
    # si el html o xml puede no ser válido:
    from amara.bindery import html
    URL = '....'  
    doc = html.parse(URL)

Instalar

Para instalar la última versión:

$ sudo pip install http://files.akara.info/00-amara-latest.tar.bz2

Es necesario tener instalado un compilador de C y la cabeceras de python (en debian/ubuntu hay que instalar python-dev





Ejemplos habituales de uso

Búsqueda por expresiones XPATH

Icon present.gif
Tip: Hay herramientas como firebug que permite copiar el XPATH de un elemento.


Búsqueda de las imágenes de un artículo
>>> from amara.bindery import html
>>> URL = 'http://heraldo.es'
>>> doc = html.parse(URL)
>>> imagenes = doc.xml_select(u'//img') # las imágenes van en etiquetas img
>>> len(imagenes)
65
>>> primera_imagen = imagenes[0]
>>> print primera_imagen.xml_encode()
<img src="/MODULOS/global/publico/interfaces/img/logo-Heraldo.png" alt="Últimas noticias de Aragón, Zaragoza, Huesca y Teruel del periódico digital Heraldo.es"/>
>>> for im in imagenes:
        print im.src
/MODULOS/global/publico/interfaces/img/logo-Heraldo.png
/uploads/imagenes/iconos/titulos/jmj.jpg
/uploads/imagenes/rec70/_cuatrovientos6_011b2ad5.jpg
...
Búsqueda de las entradas de una revista

Barrapunto publica sus entradas como

<div class="article">
<div class="generaltitle">
	<div class="title">
		<h3>
			<a href="//softlibre.barrapunto.com/">Software Libre</a>: Todo listo para la celebración de los 20 años de Linux
 
		</h3>
	</div>
</div>
<div class="details">
...		
</div>
...
</div>

Para extraer los nombres de los artículos de la primera página:

>>> from amara.bindery import html
>>> from amara.lib import U  # Extrae los nodos de texto de un fragmento
>>> articulos = doc.xml_select(u'//div[@class="article"]')
>>> len(articulos)
15
>>> for ar in articulos:
	print U(ar.div).strip()  # Navega por el nodo artículo.
                                 # Cuidado con los espacios en blanco y saltos
 
Software Libre: Todo listo para la celebración de los 20os de Linux
Publicado SmartOS, sistema operativo basado en Illumos
Un dispositivo permite a los invidentes ver a través de su lengua
El fin de la ley de Moore
...

Más ejemplos en http://wiki.xml3k.org/Amara/Recipes

Expresiones XPATH útiles
# Nodo que contenga una cadena de texto:
expresion = u'.//text()[contains(., "python")]'
expresion = u'.//text()[contains(., "%s")]' % cadena.decode('utf-8')
# Nodos o atributos que contengan una cadena:
expresion = expr = u'.//@*[contains(., "%s")]'


Inyección de marcado

Se puede transformar un documento para añadirle o quitarle información.

  • En este ejemplo añadimos unos links a los nombre de los autores, detectados por expresiones regulares:

https://github.com/zepheira/amara/blob/master/demo/inject_markup.py