Introducción
El web scraping es el proceso automatizado de recopilación de datos de sitios web mediante el uso de un script o programa. Se utiliza para extraer información como texto, imágenes y otros tipos de datos que pueden resultar útiles para diversos fines, como la investigación, el análisis de datos o el análisis de mercado.
Hoy en día, existen un montón de soluciones para el web scraping con Python. Selenium y Scrapy son algunas de las bibliotecas más utilizadas y populares. Aunque estas herramientas son excelentes para tareas de scraping complicadas, pueden resultar un poco abrumadoras para un uso ocasional.
Te presento a Parsel, la pequeña biblioteca de scraping. Esta biblioteca ligera y fácil de aprender es perfecta para proyectos pequeños y es ideal para quienes se inician en el scraping web. Es capaz de analizar HTML y extraer datos utilizando selectores CSS y XPath, lo que la convierte en una herramienta estupenda para cualquier amante de los datos que busque una forma rápida y sencilla de recopilar información de la web.
Abróchate el cinturón y prepárate para aprender a usar esta biblioteca mientras me acompañas en esta aventura de recopilación automatizada de datos. ¡Manos a la obra con el scraping!
Introducción a Parsel
Puedes instalar la biblioteca Parsel con:
pip install parsel
Ahora vamos a sumergirnos directamente en un proyecto de ejemplo y extraer todos los datos de países de este sencillo sitio web: https://www.scrapethissite.com/pages/simple/.
Para obtener el HTML del sitio web, tendrás que realizar una solicitud HTTP GET.
Realizaremos las solicitudes HTTP con la biblioteca de Python «requests», así que asegúrate de instalarla con:
pip install requests
Ahora puedes recuperar el HTML y guardarlo en un archivo:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
with open("out.html", "w", encoding="utf-8") as f:
f.write(response.text)
Y examinar la estructura:
Nuestros datos se almacenan en estructuras similares a esta:
<div class="col-md-4 country">
<h3 class="country-name">
<i class="flag-icon flag-icon-af"></i>
Afghanistan
</h3>
<div class="country-info">
<strong>Capital:</strong> <span class="country-capital">Kabul</span><br>
<strong>Population:</strong> <span class="country-population">29121286</span><br>
<strong>Area (km<sup>2</sup>):</strong> <span class="country-area">647500.0</span><br>
</div>
</div><!--.col-->
Para escribir selectores, tendrás que pasar el HTML sin procesar a Parsel:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text = raw_html)
Ahora estamos listos para escribir algunos selectores.
Extraer texto utilizando selectores CSS
Puedes mostrar la capital del primer país con:
parsel_dom = parsel.Selector(text=raw_html)
first_capital = parsel_dom.css(".country-capital::text").get()
print(first_capital)
// Output
Andorra la Vella
parsel_dom.css(".country-capital::text").get() will select the inner text of the first element that has the country-capital class.
Puedes mostrar todos los nombres de los países con:
countries_names = filter(lambda line: line.strip() != "", parsel_dom.css(".country-name::text").getall())
for country_name in countries_names:
print(country_name.strip())
// Output
Andorra
United Arab Emirates
Afghanistan
Antigua and Barbuda
Anguilla
. . .
parsel_dom.css(".country-name::text").getall() will select the inner texts of all the elements that have the "country-name" class.
Fíjate en que hemos tenido que limpiar un poco el resultado. Lo hemos hecho porque todos los elementos que tienen la clase «.country-name» también tienen una etiqueta <i> anidada en su interior. Además, el nombre del país está rodeado de muchos espacios al final.
<h3 class="country-name">
<i class="flag-icon flag-icon-ae"></i> //this is picked up as an empty string
United Arab Emirates // this is picked up as “ United Arab Emirates “
</h3>
Ahora escribamos un script para extraer todos los datos con selectores CSS:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.css(".country")
countries_data = []
for country in countries:
country_name = country.css(".country-name::text").getall()[1].strip()
country_capital = country.css(".country-capital::text").get()
country_population = country.css(".country-population::text").get()
country_area = country.css(".country-area::text").get()
countries_data.append({
"name": country_name,
"capital": country_capital,
"population": country_population,
"area": country_area
})
for country_data in countries_data:
print(country_data)
// Outputs
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'}
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
{'name': 'Afghanistan', 'capital': 'Kabul', 'population': '29121286', 'area': '647500.0'}
... Extracción de texto mediante selectores XPath
XPath es un lenguaje de consulta para seleccionar nodos de un documento XML. Son las siglas de XML Path Language, y utiliza una notación de ruta similar a la de las URL para navegar por los elementos y atributos de un documento XML. Las expresiones XPath se pueden utilizar para seleccionar un único elemento, un conjunto de elementos o un atributo específico de un elemento. XPath se utiliza principalmente en XSLT, pero también puede usarse para navegar por el Modelo de Objetos de Documento (DOM) de cualquier documento en un lenguaje similar a XML, como HTML o SVG.
XPath puede parecer intimidante al principio, pero en realidad es bastante fácil empezar a utilizarlo una vez que se comprenden los conceptos básicos y la sintaxis. Un recurso que puede resultar útil es nuestra guía de selectores XPath en https://www.webscrapingapi.com/the-ultimate-xpath-cheat-sheet.
Ahora probemos algunos selectores:
Así es como puedes imprimir la primera letra mayúscula:
parsel_dom = parsel.Selector(text=raw_html)
first_capital = parsel_dom.xpath('//*[@class="country-capital"]/text()').get()
print(first_capital)
// Output
Andorra la Vella
Y todos los nombres de países:
countries_names = filter(lambda line: line.strip() != "",
parsel_dom.xpath('//*[@class="country-name"]//text()').getall())
for country_name in countries_names:
print(country_name.strip())
// Output
Andorra la Vella
Abu Dhabi
Kabul
St. John's
The Valley
Tirana
...
Reimplementemos el script con selectores XPath:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.xpath('//div[contains(@class,"country")][not(contains(@class,"country-"))]')
countries_data = []
for country in countries:
country_name = country.xpath(".//h3/text()").getall()[1].strip()
country_capital = country.xpath(".//span/text()").getall()[0]
country_population = country.xpath(".//span/text()").getall()[1]
country_area = country.xpath(".//span/text()").getall()[2]
countries_data.append({
"name": country_name,
"capital": country_capital,
"population": country_population,
"area": country_area
})
for country_data in countries_data:
print(country_data)
// Output
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'}
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
{'name': 'Afghanistan', 'capital': 'Kabul', 'population': '29121286', 'area': '647500.0'}
...Eliminar elementos
Eliminar elementos es sencillo. Solo hay que aplicar la función drop a un selector:
selector.css(".my_class").drop()
Veamos cómo funciona esta funcionalidad escribiendo un script que elimine el campo «población» de cada país:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.css(".country")
for country in countries:
country.css(".country-population").drop()
country.xpath(".//strong")[1].drop()
country.xpath(".//br")[1].drop()
countries_without_population_html = parsel_dom.get()
with open("out.html", "w", encoding="utf-8") as f:
f.write(countries_without_population_html)

Exportar los datos
Cuando hayas terminado de extraer los datos, es importante pensar en cómo quieres guardarlos. Dos formatos habituales para almacenar este tipo de datos son .json y .csv. Sin embargo, debes elegir el que mejor se adapte a las necesidades de tu proyecto.
Exportar los datos a .json
JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos que resulta fácil de leer y escribir para las personas, y fácil de analizar y generar para las máquinas. Se utiliza a menudo para intercambiar datos entre una aplicación web y un servidor, o entre diferentes partes de una aplicación web. JSON es similar a un diccionario de Python, ya que se utiliza para almacenar datos en pares clave-valor, y puede utilizarse para almacenar y acceder al mismo tipo de datos y tener la misma estructura.
La exportación de una matriz de diccionarios de Python a .json se puede realizar con la biblioteca json:
import json
countries_dictionaries = [
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'},
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
]
json_data = json.dumps(countries_dictionaries, indent=4)
with open("data.json", "w") as outfile:
outfile.write(json_data)
// data.json
[
{
"name": "Andorra",
"capital": "Andorra la Vella",
"population": "84000",
"area": "468.0"
},
{
"name": "United Arab Emirates",
"capital": "Abu Dhabi",
"population": "4975593",
"area": "82880.0"
}
]Exportación de datos a .csv
Un CSV es una forma sencilla de almacenar datos en un archivo de texto, donde cada línea representa una fila y cada valor está separado por una coma. Se utiliza a menudo en hojas de cálculo o programas de bases de datos. Python cuenta con un excelente soporte integrado para trabajar con archivos CSV, a través de su módulo csv. Una de las características más potentes del módulo CSV es la clase DictWriter, que permite escribir un diccionario de Python en un archivo CSV de forma sencilla. Las claves del diccionario se utilizarán como encabezados de columna en el archivo CSV, y los valores se escribirán como los datos correspondientes en las filas.
A continuación se muestra cómo se puede utilizar la biblioteca csv para exportar una matriz de diccionarios de Python a un archivo .csv.
countries_dictionaries = [
{"name": "John Smith", "age": 35, "city": "New York"},
{"name": "Jane Doe", "age": 28, "city": "San Francisco"}
]
with open("data.csv", "w") as outfile:
writer = csv.DictWriter(outfile, fieldnames=countries_dictionaries[0].keys())
writer.writeheader()
for row in countries_dictionaries:
writer.writerow(row)
// data.csv
name,age,city
John Smith,35,New York
Jane Doe,28,San FranciscoConclusión
En este artículo, hemos explorado el uso de la biblioteca Parsel en Python. Hemos visto lo fácil que es utilizar los selectores CSS y XPath que ofrece Parsel para extraer datos de páginas web. En general, Parsel proporciona una solución eficiente y versátil para el web scraping. Si te interesa automatizar la recopilación de datos, sin duda deberías probarla.
¿Quieres saber más sobre el web scraping? Echa un vistazo a nuestro producto, WebScrapingAPI, y descubre cómo puedes llevar tus habilidades de extracción de datos al siguiente nivel. Nuestra potente API está diseñada específicamente para ayudarte a superar los retos más comunes del web scraping, como evitar bloqueos de IP o renderizar Javascript. ¿Y lo mejor de todo? ¡Puedes probarla gratis!




