El Web Scraping (o Scraping) son un conjunto de técnicas que se utilizan para obtener de forma automática el contenido que hay en páginas web a través de su código HTML.
Las técnicas de Scraping se pueden enmarcar dentro del campodel Big Data en la primera fase de recolección de datos para su posterior almacenamiento, tratamiento y visualización.
El uso de estas técnicas tienen como finalidad recopilar grandes cantidades de datos de diferentes páginas web cuyo uso posterior puede ser muy variado: homogenización de datos, tratamiento de contenido para la extracción de conocimiento, complementar datos en una web, etc.
A continuación adjunto una función capaz de hacer una conexión HTTP para acceder a una página web y extraer información.
La página web con la que vamos a jugar es: "https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid" que contiene datos de la lista de municipios de la Comunidad de Madrid.
In [1]:
import requests
url = "https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid"
# Realizamos la petición HTTP a la web
req = requests.get(url)
# Comprobamos que la petición nos devuelve un Status Code = 200
statusCode = req.status_code
if statusCode == 200:
print('La petición ha ido bien')
else:
print('Problemas con la petición...')
En primer lugar tenemos que hacer una petición HTTP a la página web para obtener su HTML. Para ello utilizaremos la libreria request y utilizando el método get (pasandole como parámetro la url) nos dará entre otras cosas el HTML de la web y su "Status Code".
A partir del objeto req, que almacena muchos datos relacionados con la petición HTTP (cabeceras, cookies, etc.) obtenemos el status_Code y el HTML (como un string) de la web.
In [2]:
htmlText = req.text
A partir del string htmlText que representa el código interno de la pagina web, usamos la librería beautifullSoup de Python para parsear la página y obtener los datos que nos interesan. BeautifulSoup nos aporta los métodos necesarios (y muy bien optimizados) para obtener el contenido que hay entre las etiquetas HTML.
In [3]:
from bs4 import BeautifulSoup
if statusCode == 200:
# Pasamos el contenido HTML de la web a un objeto BeautifulSoup()
html = BeautifulSoup(req.text, 'html.parser')
content = {}
# Obtenemos cada una de las filas de la tabla
rows = html.find_all('tr')
for r in rows:
#Seleccionamos las celdas de la tabla (td)
celdas = r.find_all('td')
# ignoramos la primera celda, que no tiene elementos td sino th (ver HTML de la página web)
if len(celdas)>0:
# En lugar de un separador de miles, se ha usado un caracter parecido a un espacio en blanco
# por lo que en la celda de habitantes hay que eliminar todos los caracteres que no sean números
#content.append([celdas[0].string, ''.join(c for c in celdas[1].string if c.isdigit())])
content[celdas[0].string] = { 'población': int( ''.join(c for c in celdas[1].string if c.isdigit())),
'superficie': int( ''.join(c for c in celdas[2].string if c.isdigit())),
'altitud': int( ''.join(c for c in celdas[6].string if c.isdigit())),}
Calcula la población total de todos los municipios
In [4]:
# Sol:
pobT = 0
for municipios, datos in content.items():
pobT = pobT + datos['población']
pobT
Out[4]:
In [5]:
# Sol:
# Para nota
def municipio_por_poblacion(habitantes):
pobTotal = 0
print('\nLista de municipios cuya población es superior a %d habitantes:\n' % habitantes)
for municipio, datos in content.items():
if datos['población'] > habitantes:
print(str(municipio) + ': ' + str(datos['población']))
pobTotal = pobTotal + datos['población']
return print('\nLa población total de todos estos municipios es: ' + str(pobTotal)+'\n')
municipio_por_poblacion(50000)
In [6]:
# Sol:
print('\nLista de municipios cuya altitud es superior a 700m:\n')
for municipio, datos in content.items():
if datos['altitud'] > 700:
print(municipio)
In [8]:
# Sol:
# Para nota
def municipio_por_altitud(altitud):
print('\nLista de municipios cuya altitud es superior a %dm:\n' % altitud)
for municipio, datos in content.items():
if datos['altitud'] > altitud:
print(str(municipio) + ': ' + str(datos['altitud']) + 'm')
return
municipio_por_altitud(1200)
In [ ]: