Herramientas de usuario

Herramientas del sitio


informatica:programacion:cursos:python_avanzado_proyectos_seguridad:extraccion_contenidos_web_python

¡Esta es una revisión vieja del documento!


Extracción de contenidos web con Python

Módulo perteneciente al curso Python avanzado para proyectos de seguridad

Entre las técnicas que disponemos para extraer contenidos de la web podemos destacar:

  • Screen scraping: Técnica que permite obtener información moviéndote por la pantalla, por ejemplo registrando los clicks del usuario.
  • Web scraping: Trata es obtener la información de un recurso como por ejemplo de una página web en HTML y procesa esa información para extraer datos relevantes.
  • Report mining: Técnica que también pretende obtener información, pero en este caso a partir de un archivo (HTML, RDF, CSV, etc). Con esta aproximación de definición podemos crear un mecanismo simple y rápido sin necesidad de escribir una API y como caracterí­stica principal podemos indicar que el sistema no necesita de una conexión ya que al trabajar a partir de un fichero es posible extraer la información de forma offline y sin necesidad de utilizar ninguna API.
  • Spider: Los spiders (crawlers/arañas) son scripts o programas que siguen unas reglas para moverse por un sitio web y tienen como objetivo recolectar información imitando la interacción que realizaría un usuario con el sitio web. La idea es que sea solo necesario escribir las reglas para extraer los datos que nos interesen y dejar que el spyder rastree todo el sitio web en busca de enlaces.

En esta unidad didáctica nos vamos a centrar en la técnica de webscraping que permite la recolección o extracción de datos de páginas web de forma automática. Es un campo muy activo y en continuo desarrollo que comparte objetivos con la web semántica, el procesamiento de textos automático, inteligencia artificial e interacción humano-computador.

El web scraping es una técnica que permite la extracción de información de sitios web, transformando datos no estructurados como los datos en formato HTML en datos estructurados.

IMAAAAAAAAAAAAAAAAAAAAAGEN

En esta unidad revisaremos el módulo lxml junto con los parsers xml, html y el módulo BeautifulSoup.

Complementamos el uso de estos módulos con el módulo requests para realizar peticiones y descargar el código HTML.

Por ejemplo, BeautifulSoup recibirá el contenido de la respuesta con el objetivo analizar el código HTML del sitio web y extraer los datos que nos interesen.

Parsers XML y HTML

Dentro del ecosistema de python encontramos diferentes módulos que nos puedes ayudar a parsear un documento que se encuentra en formato xml y html.

El módulo lxml es un módulo que une las librerías libxml2 para análisis de documentos XML y libxslt. Las principales características del módulo son:

  • Soporte para documentos XML y HTML
  • Dispone de una API basada en ElementTree
  • Soporte para seleccionar elementos del documento mediante expresiones XPath

La instalación de este parser se puede hacer a través del repositorio oficial de python:

pip install lxml

En este primer ejemplo vamos a hacer uso del módulo lxml.etree que se trata de un submódulo dentro de la librería lxml, que proporciona métodos como XPath(), que soporta expresiones utilizando como sintaxis selectores XPath.

Con este ejemplo vemos el uso del parser lxml para leer un fichero html y extraer el texto de la etiqueta title del documento html a través de una expresión Xpath.

Puede encontrar el siguiente código en el fichero obtener_title_xpath.py:

#!/usr/bin/env python3
 
import re
import requests
 
from lxml import etree
 
respuesta = requests.get('https://www.debian.org/releases/stable/index.en.html')
 
parser = etree.HTML(respuesta.text)
 
resultado = etree.tostring(parser,pretty_print=True, method="html")
#print(resultado)
 
obtener_texto_xpath = etree.XPath("//title/text()", smart_strings=False)
texto = obtener_texto_xpath(parser)[0]
print(texto)

Submódulo lxml.html

El módulo lxml también provee un submódulo de Python llamado lxml.html dedicado para trabajar con HTML.

En el siguiente ejemplo vamos a estudiar el mismo ejemplo que el caso anterior, esta vez utilizando el parser HTML.

Puede encontrar el siguiente código en el fichero obtener_title_xpath_parser_html.py:

#!/usr/bin/env python3
 
import re
import requests
 
from lxml import html
 
respuesta = requests.get('https://www.debian.org/releases/stable/index.en.html')
elementos = html.fromstring(respuesta.text)
obtener_texto_xpath = elementos.xpath("//title/text()", smart_strings=False)
texto = obtener_texto_xpath[0]
print(texto)

Extraer etiquetas de un sitio web con el módulo lxml

Antes de comenzar a analizar el código HTML, necesitamos extraer el contenido analizar.

En este ejemplo vamos a obtener la versión y el nombre en clave de la última versión estable de Debian del sitio web de Debian: https://www.debian.org/releases/stable/index.en.html

La información que queremos se muestra en el título de la página y en el primer párrafo.

Primero lo que tenemos que hacer es descargar la página con el módulo requests:

import requests
response = requests.get('https://www.debian.org/releases/stable/index.en.html')

Posteriormente, analizamos el código fuente en un árbol ElementTree. Esto es lo mismo que analizar XML con ElementTree de la biblioteca estándar, excepto que aquí usaremos el parser HTML disponible en el módulo lxml:

from lxml.etree import HTML
root = HTML(response.content)

La función HTML() es un acceso directo que lee el código HTML que se le pasa y produce un árbol XML. Tenga en cuenta que estamos pasando response.content y no response.text. El módulo lxml produce mejores resultados cuando utiliza la respuesta sin procesar.

La implementación de ElementTree de la biblioteca lxml ha sido diseñada para ser 100 % compatible con la biblioteca estándar, por lo que podemos comenzar a explorar el documento de la misma manera que lo hicimos con XML. Por ejemplo podemos obtener las etiquetas raíz que se encuentran en un documento html.

>>> [e.tag for e in root]
 
['head', 'body']

Si nos interesa el contenido de texto del elemento <title> del documento html, podríamos hacerlo de la siguiente forma:

>>> root.find('head').find('title').text
'Debian -- Debian "stretch" Release Information '

Obtener formularios de un sitio web

<p>En este ejemplo realizamos una petición al buscador duckduckgo y obtenemos el formulario que se utiliza para realizar las búsquedas.</p>

<p>Para ello accedemos al objeto <strong>forms</strong> que se estará contenido dentro de la respuesta de la url.</p>

<p>Puede encontrar el siguiente código en el fichero<strong>&nbsp;duckduckgo.py:</strong></p>

#!/usr/bin/env python3
 
from lxml.html import fromstring, tostring
from lxml.html import parse, submit_form
 
import requests
response = requests.get('https://duckduckgo.com')
form_page = fromstring(response.text)
form = form_page.forms[0]
print(tostring(form))
 
page = parse('http://duckduckgo.com').getroot()
print(tostring(page))
page.forms[0].fields['q'] = 'python'
busqueda = parse(submit_form(page.forms[0])).getroot()
print(tostring(busqueda))

<p>Este es el resultado de la primera parte del script, donde podemos ver el <strong>objeto de formulario de DuckDuckGo</strong>:</p>

b'<form id="search_form_homepage" class="search search--home js-search-
       form" name="x" method="POST" action="/html">\n\t\t\t<input
        id="search_form_input_homepage" class="search__input js-search-input"
       type="text" autocomplete="off" name="q" tabindex="1"
        value="">\n\t\t\t<input id="search_button_homepage" class="search__button
         js-search-button" type="submit" tabindex="2" value="S">\n\t\t\t<input
         id="search_form_input_clear" class="search__clear empty js-search-clear"
        type="button" tabindex="3" value="X">\n\t\t\t<div
         id="search_elements_hidden" class="search__hidden js-search-
        hidden"></div&amp;gt;\n\t\t</form&amp;gt;\n\n\t\t\t\t\t\t'
informatica/programacion/cursos/python_avanzado_proyectos_seguridad/extraccion_contenidos_web_python.1731584425.txt.gz · Última modificación: por tempwin