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:
- Cargar una página web
- 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 |
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
- Ingresar por el navegador a la url deseada, en nuestro caso: http://www.timeanddate.com/weather/china/beijing
- 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 |
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 |
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 |
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.
-
-
Gracias por el aporte. Saludos. 🙂
-
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 😉
-
-
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
-
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.
-
-
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.
-
Recién busque en google "install library qpython", hay varios documentos que quizá te sean de ayuda. Saludos
-
-
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.-
Hola Federico. Te está faltando el paquete "lxml"
Para android no tengo mucha idea, te dejo el enlace de GitHub --> https://github.com/qpython-androidCon PIP puedes instalarlo - pip install lxml
Saludos
-
-
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.
-
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
-
Excelente aporte Brian. Saludos!!!
-
-
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.-
-
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.
-
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/"
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.-
-
Me alegro que solucionaras. Saludos!!!
-
-
Este comentario ha sido eliminado por el autor.
-
Muy buen ejemplo, hace poco que estoy usando estas tecnicas.
-
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?-
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
-
-
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???
-
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 -
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!
-
Excelente, ayer estuve mirando la librería Selenium y quedé con ganas de escribir una entrada sobre la misma. Gracias por la info!!!
Saludos
-
-
Muchas gracias, me has ayudado muchisimo
-
Me alegro mucho. Gracias por visitar el blog
-
-
hola, me parecio muy interesante tu articulo, existe alguna forma para logearte a una pagina conbeautifulsoup
-
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
Buenísimo, no tenia idea del Web Scraping. Ya hice una prueba con el clima de mi ciudad del sitio web del SMN.