En este artículo, demostraremos cómo recopilar datos del sitio web Booking.com con Python. Obtendremos información que incluye, entre otros, nombres de hoteles, valoraciones, precios, direcciones de ubicación y sus descripciones. El código proporcionado permite recuperar datos de las páginas de los hoteles analizando el contenido HTML y extrayendo los datos JSON incrustados.
Antes de ejecutar el código para scrapear datos de Booking.com, necesitarás instalar las librerías Python necesarias. Aquí te explicamos cómo puedes instalar las dependencias necesarias:
Para instalar las bibliotecas necesarias, puede utilizar pip:
pip install requests lxml
Estas son las únicas librerías externas que necesitas, y el resto (json, csv) vienen preinstaladas con Python.
A la hora de scrapear datos de Booking.com, es importante entender la estructura de la página web y el tipo de datos que quieres extraer. Cada página de hotel en Booking.com contiene datos estructurados incrustados en forma de JSON-LD, un formato que permite extraer fácilmente detalles como el nombre, la ubicación y el precio. Vamos a raspar estos datos.
Dado que Booking.com es un sitio dinámico e implementa medidas para combatir las acciones automatizadas, utilizaremos cabeceras HTTP y proxies adecuados para garantizar un scraping fluido sin riesgo de bloqueo.
Las cabeceras imitan una sesión de usuario en un navegador y evitan la detección por parte de los sistemas anti-scraping de Booking.com. Sin unas cabeceras bien configuradas, el servidor puede identificar fácilmente los scripts automatizados, lo que puede provocar bloqueos de IP o retos de captcha.
Para evitar ser bloqueados por los mecanismos anti-scraping de Booking.com, utilizaremos cabeceras personalizadas para simular un usuario legítimo navegando por el sitio web. A continuación te explicamos cómo enviar una petición HTTP con las cabeceras adecuadas:
import requests
from lxml.html import fromstring
urls_list = ["https links"]
for url in urls_list:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Linux"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
}
response = requests.get(url, headers=headers)
El uso de proxies es necesario cuando se scrapean sitios como Booking.com, que aplican estrictos límites de tasa de peticiones o rastrean direcciones IP. Los proxies ayudan a distribuir la carga de peticiones entre diferentes direcciones IP, evitando bloqueos. Para ello, se pueden utilizar tanto proxies gratuitos como servicios proxy de pago con autenticación por nombre de usuario y contraseña o dirección IP. En nuestro ejemplo, utilizamos esta última opción.
proxies = {
'http': '',
'https': ''
}
response = requests.get(url, headers=headers, proxies=proxies)
Después de enviar la solicitud, analizamos el contenido HTML utilizando lxml para localizar los datos JSON-LD incrustados que contienen detalles del hotel. Este paso extrae los datos estructurados de la página web que incluyen nombres de hoteles, precios, ubicaciones y más.
parser = fromstring(response.text)
# Extraer datos JSON incrustados
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])
Una vez que tenemos los datos JSON parseados, podemos extraer campos relevantes como el nombre del hotel, la dirección, la valoración y el precio. A continuación se muestra el código para extraer la información del hotel desde el JSON:
name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
# Añade los datos a la lista all_data
all_data.append({
"Name": name,
"Location": location,
"Price Range": priceRange,
"Rating": ratingValue,
"Review Count": reviewCount,
"Type": type_,
"Postal Code": postalCode,
"Address Locality": addressLocality,
"Country": addressCountry,
"Region": addressRegion,
"Street Address": streetAddress,
"URL": url,
"Image URL": image_url,
"Room Types": room_types
})
Una vez extraídos los datos, podemos guardarlos en un archivo CSV para su posterior análisis:
# Una vez procesadas todas las URL, escriba los datos en un archivo CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code",
"Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# Escribir la cabecera
writer.writeheader()
# Escribir las filas de datos
writer.writerows(all_data)
Aquí está el código completo combinando todas las secciones:
import requests
from lxml.html import fromstring
import json
import csv
# Lista de URL de hoteles que se van a raspar
urls_list = [
"Https link",
"Https link"
]
# Inicializar una lista vacía para contener todos los datos raspados
all_data = []
proxies = {
'http': ''
}
# Recorre cada URL para extraer datos
for url in urls_list:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Linux"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
}
# Envío de la solicitud al sitio web
response = requests.get(url, headers=headers, proxies=proxies)
# Análisis del contenido HTML
parser = fromstring(response.text)
# Extraer datos JSON incrustados
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])
# Extraer todos los detalles del hotel de JSON
name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
# Añade los datos a la lista all_data
all_data.append({
"Name": name,
"Location": location,
"Price Range": priceRange,
"Rating": ratingValue,
"Review Count": reviewCount,
"Type": type_,
"Postal Code": postalCode,
"Address Locality": addressLocality,
"Country": addressCountry,
"Region": addressRegion,
"Street Address": streetAddress,
"URL": url,
"Image URL": image_url,
"Room Types": room_types
})
# Una vez procesadas todas las URL, escriba los datos en un archivo CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code",
"Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# Escribir la cabecera
writer.writeheader()
# Escribir las filas de datos
writer.writerows(all_data)
print("Data successfully saved to booking_data.csv")
Este artículo mostraba cómo scrapear datos de hoteles de Booking.com usando Python. Hicimos hincapié en la importancia de utilizar cabeceras HTTP y proxies adecuados para eludir las medidas anti-scraping. Los datos extraídos se pueden guardar en un archivo CSV para su posterior análisis. Al hacer scraping de sitios web, comprueba siempre las condiciones del servicio para evitar infringirlas.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Comentarios: 0