Web Scraping con Python y BeautifulSoup

Web Scraping con Python y BeautifulSoup
Web Scraping con Python y BeautifulSoup

Hace tiempo tenía ganas de escribir sobre web scraping utilizando Python, para el que no conozca, sería lo mismo que decir "Extraer datos de paginas web utilizando Python".

Los motivos de escribir sobre el tema son muchos, pero enumero algunos:
1 - Hay muchos pedidos de trabajos en lo que respecta a la extracción de datos  web
2 - En el momento el tiempo que tengo para escribir en el blog no es mucho y me gustaría que este tema vaya quedando registrado en el "Diario".
3 - Luego de incursionar un poco en este mundo del Scraping se darán cuenta de lo mucho que se puede hacer con algunas lineas de código y un poco de imaginación.

Comparto el repositorio de GitHub: https://github.com/DiegoCaraballo/Web-Scraping-con-Python-y-BeautifulSoup.git

Un tema a tener en cuenta a la hora de meternos a extraer datos mediante scripts en una página web es leer los Términos y Condiciones de la página raspada, ya que hay muchas paginas que "no lo permiten".
También comentarles que sería apropiado tener algún conocimiento de HTML para que no resulte tedioso.

Demás esta decir que debemos tener instalado python. Las pruebas que comparto más abajo las hice en un sistema Linux, pero en otras oportunidades lo he hecho en Windows y funcionan correctamente.
1 - Como instalar Python en Linux
2 - Como instalar Python en Windows

Las herramientas
Las tareas básicas para extraer los datos de un sitio son dos:

  1. Cargar una página web
  2. Analizar el HTML de la página para localizar los datos que nos interesan

Python nos ofrece dos excelentes herramientas para las tareas antes mencionadas. Vamos a utilizar requests para cargar una pagina web y BeautifulSoup para hacer el análisis.

Para instalar estas librerías podemos utilizar pip:

  • $ pip install requests
  • $ pip install beautifulsoup4

Puedes ver también: Como instalar pip en Linux y Windows


BeautifulSoup nos proporciona algunos métodos simples y Pythonicos para navegar y buscar extraer lo que necesitamos.

Técnica de Scraping Básica
Lo primero que debemos hacer a la hora de querer extraer datos de una/s pagina web es inspeccionar manualmente la pagina para determinar como podemos localizar los datos.
Para comenzar, vamos a extraer algunos datos del blog, como por ejemplo su título y todas sus páginas internas. También puedes probar con la URL que quieras.

En los comentarios del código les explico cada línea:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Sitio: https://www.pythondiario.com
# Autor: Diego Caraballo

# Haciendo pruebas con BeautifulSoup y requests

# Importamos las librerias
from bs4 import BeautifulSoup
import requests

# Capturamos la url ingresada en la variable "url"
url = raw_input("Ingrese la URL: ")

# Capturamos el hml de la pagina web y creamos un objeto Response
r  = requests.get("http://" +url)
data = r.text
print ""

# Creamos el objeto soup y le pasamos lo capturado con request
soup = BeautifulSoup(data, 'lxml')

# Capturamos el titulo de la página y luego lo mostramos
# Lo que hace BeautifulSoup es capturar lo que esta dentro de la etiqueta title de la url
titulo = soup.title.text
print "El titulo de la pagina es: " + titulo
print ""

# Buscamos todas etiquetas HTML (a) y luego imprimirmos todo lo que viene despues de "href"
for link in soup.find_all('a'):
    print(link.get('href'))

Como dije anteriormente, esto nos devolverá los el título de la página y los enlaces de la misma.

Script que devuelve Titulo y enlaces de una pagina cualquiera
Script que devuelve Titulo y enlaces de una pagina cualquiera

Ahora veremos otro ejemplo de como utilizar BeautifulSoup.

Lo que haremos ahora será extraer la temperatura en Beijing (China), no me preguntes porque elegí china jeje, espero que los administradores de la página no se enojen 😉

Lo que hace el script es ingresar en la página, obtener los datos necesarios (temperatura y sensación térmica) y mostrarlos infinitamente cada X segundos (en mi caso puse 15seg para que se aprecie). Cada vez que la pagina actualice la temperatura, nuestro script también actualizara los datos sin tener que estar entrando en la pagina (lindo no?). ¿Se imaginan haciendo una página que se provea de información desde otros sitios haciendo scraping? Si, se puede!!!, de hecho, hay millones 😉

En los comentarios del código explico lo que hace. Para obtener los datos deseados debemos hacer lo siguiente:

Las pruebas las hice con el navegador Mozilla, pero también las he hecho en Chrome

  1. Ingresar por el navegador a la url deseada, en nuestro caso: http://www.timeanddate.com/weather/china/beijing
  2. Dentro de la página, buscamos el dato a extraer. Mostraré el ejemplo de la temperatura, pero para la sensación térmica es igual.
Temperatura en Beijing
Temperatura en Beijing

    3. Ahora hacemos clic con el botón secundario en el 27 y elegimos "Inspeccionar elemento", veremos algo como lo siguiente:

Etiquetas que contienen la temperatura
Etiquetas que contienen la temperatura

    4. Lo que necesitamos nosotros para obtener la temperatura, es sacar lo que está dentro de la etiqueta "div" (class - h2), la temperatura. Esto lo capturamos con BeautifulSoup y lo devolvemos como texto.

    5. En un principio quizá nos resulte complicado, pero la practica ayuda mucho. También comentarles que cada página es un mundo a parte, debemos inspeccionarla y buscarle la vuelta para extraer los datos.

Les dejo el código:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Sitio: https://www.pythondiario.com
# Autor: Diego Caraballo

# Haciendo pruebas con BeautifulSoup y requests

# Importamos las librerias
from bs4 import BeautifulSoup
import requests
import time
import os

# Creamos el Bucle infinito
while True:

 # Capturamos la url 
 url = "http://www.timeanddate.com/weather/china/beijing"

 # Capturamos el hml de la pagina web y creamos un objeto Response
 r  = requests.get(url)
 data = r.text

 # Creamos el objeto soup y le pasamos lo capturado con request
 soup = BeautifulSoup(data, 'lxml')

 # Buscamos el div para sacar los grados
 temp = soup.find_all('div', class_="h2")

 # Buscamos el div para sacar la sensacion termica
 sTerm = soup.find_all('div', class_="clear")
        
        # Con [0] saco el primer elemento y con [1] el segundo
 print "La temperatura en Beijing: " + temp[0].text
 print "La sesacion termica: " + sTerm[1].text
 
 # Tiempo en segundos para ejecutarse nuevamente
 time.sleep(15)
 
 # Boramos los datos viejos, para Windows es "cls"
 os.system("clear")

Script que devuelve temperatura
Script que devuelve temperatura

Solo resta decir que tengo más por compartirles, pero lo veremos en futuras entradas. Pueden seguir investigando por su cuenta y cualquier aporte o comentario siempre es bienvenido. Saludos, Diego.

  1. CURSO dice:

    Buenísimo, no tenia idea del Web Scraping. Ya hice una prueba con el clima de mi ciudad del sitio web del SMN.

    1. CURSO dice:

      Gracias por el aporte. Saludos. 🙂

    2. PythonDiario dice:

      Excelente Emanuel, lo de extraer el clima fue un ejemplo sencillo, pero metiendo mano puedes hacer mucha cosa. Cuando tenga algo nuevo armado lo compartiré. Saludos y gracias por visitar el blog 😉

  2. Disperso dice:

    Hola. Utilizo Qpython y he conseguido meter la librería requests pero no se que librería habría que meter para el BeautifulSoup me da error el bs4

    1. PythonDiario dice:

      Hola, he utilizado QPython solo un par de veces, no sabría decirte como instalarle librerías, pero por lo que veo te falta la librería "bs4" que contiene BeautifulSoup. Saludos y gracias por visitar el blog.

  3. fede dice:

    Gracias Diego. He bajado bs4 y he metido la carpeta en el mismo directorio que metí requests pero me sigue dando error. Seguiré investigando. Estoy muy interesado en el Scraping.

    1. PythonDiario dice:

      Recién busque en google "install library qpython", hay varios documentos que quizá te sean de ayuda. Saludos

  4. fede dice:

    Gracias por tu paciencia Diego. La verdad es que estoy aprendiendo mucho con las dificultados. no me rindo. He conseguido bajar pip, con el, meter requests y beautifulsoup, tanto en la tablet como en windows, pero... en ambos sitios al utilizar el beautifulsoup (data, 'lxml') me da el siguiente error:
    Traceback (most recent call last):
    File "C:/Python27/url.py", line 7, in
    soup=BeautifulSoup(data, 'lxml')
    File "C:Python27libsite-packagesbs4__init__.py", line 165, in __init__
    % ",".join(features))
    FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
    Alguna idea? Saludos.

    1. PythonDiario dice:

      Hola Federico. Te está faltando el paquete "lxml"
      Para android no tengo mucha idea, te dejo el enlace de GitHub --> https://github.com/qpython-android

      Con PIP puedes instalarlo - pip install lxml

      Saludos

  5. fede dice:

    Ya me rindo. He intentado instalar el lxml en android, en windows, para python 2.7 y 3.6 y nada. En el 2.7 para windows me pedia algo de visual c y lo he instalado, pero despues al volver a instalar lxml me daba errores de que faltaban carpetas. En el 3.6 me pide que instale el visual c++ y ya me he cansado. En casa tengo una maquina con linux, lo intentare alli. Gracias por tu ayuda y perdona el c...Saludos.

    1. Unknown dice:

      Federico en Windows debes instalar lxml desde el MS Windows Installer packages descargalo de aquí https://pypi.python.org/pypi/lxml/3.3.5#downloads

    2. PythonDiario dice:

      Excelente aporte Brian. Saludos!!!

  6. CURSO dice:

    Hola a todos.

    Quiero dejarles una duda que tengo:

    " a href="?contID=XXXX" class="button lime">Leer m�s →</a "

    De la linea anterior, me interesaría sacar el dato que está dentro de href entre colmillada. Al hacer la prueba, obtuve el dato "Leer más" y no es lo que quiero, sino "?contID=XXXX". Es parte de la URL de un articulo. ¿Es posible?

    Espero que se entienda mi planteo.

    Muchas gracias a todos por su tiempo. Saludos.-

    1. PythonDiario dice:

      Hola Emanuel, como estas?
      Es una url específica? o son varias?

      from bs4 import BeautifulSoup

      html = # your HTML

      soup = BeautifulSoup(html)

      for item in soup.find_all(attrs={'class': 'nombre de clase'}):
      ----for link in item.find_all('a'):
      --------print link.get('href')

      Ahi te va a mostrar las url enteras de la clase seleccionada. Puedes capturar las URL como string en una lista y extraer la que tu necesitas. Luego crear alguna simple función que te devuelva parte de la URL.

      Es lo que se me ocurre ahora, pero calculo BeautifulSoup tiene algo más sencillo.

      Saludos, Diego.

    2. CURSO dice:

      Muchas gracias por tu pronta respuesta, me ayudo mucho.

      Del sitio que quiero extraer los datos, cada articulo tiene la url a "medias".

      Lo que me sirvió fue "print link.get('href')" obviamente que use otra variable en lugar de link y no necesite el ciclo for.

      Luego tengo que hacer lo siguiente:

      d = web[0]
      RN = "http://rionegro.gov.ar/&quot;
      temp = d.get('href')

      print RN + temp

      y el resultado sería el siguiente: http://rionegro.gov.ar/?contID=31632

      Si yo hago "print web[0]" lo que obtengo es:

      " a class="button lime" href="?contID=31632">Leer más →</a "

      No se si se entiende mi explicación, pero básicamente logré lo que necesitaba y muchas gracias por tu ayuda nuevamente. Saludos.-

    3. PythonDiario dice:

      Me alegro que solucionaras. Saludos!!!

  7. CURSO dice:

    Este comentario ha sido eliminado por el autor.

  8. Caminos de la Oscuridad. dice:

    Muy buen ejemplo, hace poco que estoy usando estas tecnicas.

  9. Observatorio Fobos dice:

    Hola amigo, estoy utilizando windows 10 me da el siguiente problema

    Traceback (most recent call last):
    File "MostrarEnlaces.py", line 21, in
    soup = BeautifulSoup(data, 'lxml')
    File "C:Python27libsite-packagesbs4__init__.py", line 165, in __init__
    % ",".join(features))
    bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?

    1. PythonDiario dice:

      Hola Edudardo, gracias por visitar el blog. Prueba sacar la linea 'lxml'. O si no prueba instalar el módulo lxml

      Luego me cuentas!!!

      Saludos

  10. Anónimo dice:

    Hola! Me he estado instruyendo en esto del scraping y me asalta una duda... puedo extraer datos de una pagina en la cual previamente realize una busqueda?, ejemplo, una pagina me ofrece mostrar un resultado luego de ingresar ciertos datos, ese resultado lo quiero capturar, es posible hacerlo con esta tecnologia???

    1. PythonDiario dice:

      Hola, gracias por visitar el blog. Me imagino podrías con la librería Mechanize. Hace tiempo escribi una simple entrada de como utilizar el módulo, quizá tengas que profundizar!!! Te dejo la entrada por si te interesa, saludos
      Completar formularios con mechanize y BeautifulSoup

    2. Anónimo dice:

      Hola Diego, use lo que me indicaste y no encontre forma de aplicarlo con la busqueda con un objeto button que realizaba el proceso de busqueda, entre tanto leer y buscar encontre dentro de mismo Python la libreria Selenium, que me permite enviar datos a la pagina que quiero buscar y puedo manipular el boton en particular para que realice lo que necesito, ahora estoy viendo la forma de capturar dicha pagina luego de la busqueda y mostrar lo que necesito exclusivamente, muchas gracias por tu tiempo!

    3. PythonDiario dice:

      Excelente, ayer estuve mirando la librería Selenium y quedé con ganas de escribir una entrada sobre la misma. Gracias por la info!!!
      Saludos

  11. Anónimo dice:

    Muchas gracias, me has ayudado muchisimo

    1. PythonDiario dice:

      Me alegro mucho. Gracias por visitar el blog

  12. Unknown dice:

    hola, me parecio muy interesante tu articulo, existe alguna forma para logearte a una pagina conbeautifulsoup

  13. Unknown dice:

    Buen dia en la actualidad estoy en la fase de preparación de un proyecto academico en web scraping de redes sociales, para realizar analisis de datos de paginas en las mismas para medir comportamiento de mercados, si alguien tiene experiencia en scraping de redes por favor una manito, por favor.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir
White Monkey