Libera el poder de los datos: Cómo extraer información valiosa de Booking.com

Raluca Penciuc el 07 abr 2023

blog-image

Como agencia de viajes online líder, Booking.com es un tesoro de datos valiosos sobre hoteles y alquileres vacacionales de todo el mundo. Desde opiniones de huéspedes hasta precios y disponibilidad, la información disponible en Booking puede ser increíblemente útil para una amplia gama de propósitos.

Tanto si eres un empresario que evalúa a la competencia como si eres un científico de datos que analiza las tendencias del sector de la hostelería, el web scraping es una potente herramienta que puede ayudarte a recopilar los datos que necesitas de las páginas de Booking.

Al final de este tutorial, usted tendrá una comprensión sólida de cómo raspar Booking.com utilizando la popular biblioteca de automatización Node.js Puppeteer. Nos centraremos en la extracción de detalles de anuncios de Madeira, Portugal, pero las técnicas y conceptos cubiertos en este tutorial se pueden aplicar a otros sitios web y puntos de datos también.

Requisitos previos

Si aún no tienes configurado tu entorno Node.js, dirígete a su sitio web oficial para descargar la última versión para tu sistema operativo. A continuación, crea un nuevo directorio y ejecuta el siguiente comando para inicializar tu proyecto:

npm init -y

Utilizaremos TypeScript para escribir el código. Este superconjunto de JavaScript añade tipado estático opcional y otras características. Es útil para proyectos más grandes y puede hacer que sea más fácil detectar errores desde el principio. Necesitas añadirlo a las dependencias dev del proyecto e inicializar su archivo de configuración:

npm install typescript -save-dev npx tsc -init

Sólo asegúrese de que en el nuevo archivo generado tsconfig.json, la propiedad "outDir" se establece en "dist", ya que tenemos la intención de separar el código TypeScript del compilado.

Por último, el siguiente comando añadirá Puppeteer a las dependencias de nuestro proyecto:

npm install puppeteer

Puppeteer es una biblioteca Node.js que proporciona una API de alto nivel para controlar un navegador Chrome sin cabeza, que se puede utilizar para el web scraping y la tarea de automatización

Localización de los datos

Para este tutorial hemos elegido raspar las propiedades disponibles en las Islas Madeira, Portugal: https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15. Es importante añadir las fechas de entrada y salida a la URL para que toda la información de la propiedad esté disponible.

Esta guía cubre la extracción de los siguientes datos de propiedad:

  • el nombre
  • la URL
  • la dirección física
  • el precio
  • la calificación y el recuento de las reseñas
  • la miniatura

Puede verlos resaltados en la siguiente captura de pantalla:

blog-image

Abriendo las Herramientas de Desarrollador en cada uno de estos elementos podrás notar los selectores CSS que usaremos para ubicar los elementos HTML. Si eres bastante novato en el funcionamiento de los selectores CSS, no dudes en consultar esta guía para principiantes.

Análisis de los datos

Como todos los listados tienen la misma estructura y los mismos datos, podemos extraer toda la información de la lista completa de propiedades en nuestro algoritmo. Después de ejecutar el script, podemos recorrer todos los resultados y compilarlos en una sola lista.

Tras un primer vistazo al documento HTML, te habrás dado cuenta de que el sitio web de Booking es bastante complejo y los nombres de las clases se generan en su mayoría de forma aleatoria.

blog-image

Por suerte para nosotros, el sitio web no se basa únicamente en los nombres de las clases, y podemos utilizar el valor de un atributo específico como criterio de extracción. En la captura de pantalla anterior, destacamos lo accesibles que son la miniatura, el nombre y la URL de una propiedad.

import puppeteer from 'puppeteer';

async function scrapeBookingData(booking_url: string): Promise<void> {

// Launch Puppeteer

const browser = await puppeteer.launch({

headless: false,

args: ['--start-maximized'],

defaultViewport: null

})

const page = await browser.newPage()

// Navigate to the channel URL

await page.goto(booking_url)

// Extract listings name

const listings_name = await page.evaluate(() => {

const names = document.querySelectorAll('div[data-testid="title"]')

const names_array = Array.from(names)

return names ? names_array.map(n => n.textContent) : []

})

console.log(listings_name)

// Extract listings location

const listings_location = await page.evaluate(() => {

const locations = document.querySelectorAll('a[data-testid="title-link"]')

const locations_array = Array.from(locations)

return locations ? locations_array.map(l => l.getAttribute('href')) : []

})

console.log(listings_location)

// Extract listings thumbnail

const listings_thumbnail = await page.evaluate(() => {

const thumbnails = document.querySelectorAll('[data-testid="image"]')

const thumbnails_array = Array.from(thumbnails)

return thumbnails ? thumbnails_array.map(t => t.getAttribute('src')) : []

})

console.log(listings_thumbnail)

await browser.close()

}

scrapeBookingData("https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15")

Utilizamos Puppeteer para abrir una instancia del navegador, crear una nueva página, navegar a nuestra URL de destino, extraer los datos mencionados, y luego cerrar el navegador. Para propósitos de depuración visual, estoy usando el modo no headless del navegador.

Como ya se ha explicado, los datos eran fácilmente accesibles gracias al atributo "data-testid" que asignaba un valor único al elemento HTML. Ejecute el siguiente comando para ejecutar el script:

npx tsc && node dist/index.js

Su terminal debería mostrar 3 resultados de lista del mismo tamaño, representando los nombres, las URLs y las miniaturas de todas las propiedades de la página actual.

blog-image

Para la siguiente sección del documento HTML, resaltamos la dirección, la valoración y el recuento de opiniones de una propiedad.

// Extract listings address

const listings_address = await page.evaluate(() => {

const addresses = document.querySelectorAll('[data-testid="address"]')

const addresses_array = Array.from(addresses)

return addresses ? addresses_array.map(a => a.textContent) : []

})

console.log(listings_address)

// Extract listings rating and review count

const listings_rating = await page.evaluate(() => {

const ratings = document.querySelectorAll('[data-testid="review-score"]')

const ratings_array = Array.from(ratings)

return ratings ? ratings_array.map(r => r.textContent) : []

})

console.log(listings_rating)

Como antes, hemos utilizado el atributo "data-testid". Ejecutando de nuevo el script deberías ver 2 listas más, igual que las anteriores.

blog-image

Y finalmente, en el último apartado, extraemos el precio de la vivienda. El código no será diferente de lo que hicimos antes:

// Extract listings price

const listings_price = await page.evaluate(() => {

const prices = document.querySelectorAll('[data-testid="price-and-discounted-price"]')

const prices_array = Array.from(prices)

return prices ? prices_array.map(p => p.textContent) : []

})

console.log(listings_price)

Para facilitar el tratamiento posterior de los datos extraídos, combinaremos las listas resultantes en una sola.

// Group the lists

const listings = []

for (let i = 0; i < listings_name.length; i++) {

listings.push({

name: listings_name[i],

url: listings_location[i],

address: listings_address[i],

price: listings_price[i],

ratings: listings_rating[i],

thumbnails: listings_thumbnail[i]

})

}

console.log(listings)

El resultado final debería ser el siguiente:

[

{

name: 'Pestana Churchill Bay',

url: 'https://www.booking.com/hotel/pt/pestana-churchill-bay.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=1&hapos=1&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=477957801_262227867_0_1_0&highlighted_blocks=477957801_262227867_0_1_0&matching_block_id=477957801_262227867_0_1_0&sr_pri_blocks=477957801_262227867_0_1_0__18480&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

address: 'Câmara de Lobos',

price: '911 lei',

ratings: '9.0Wonderful 727 reviews',

thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/202313893.webp?k=824dc3908c4bd3e80790ce011f763f10fd4064dcb5708607f020f2e7c92d130e&o=&s=1'

},

{

name: 'Hotel Madeira',

url: 'https://www.booking.com/hotel/pt/madeira-funchal.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=2&hapos=2&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=57095605_262941681_2_1_0&highlighted_blocks=57095605_262941681_2_1_0&matching_block_id=57095605_262941681_2_1_0&sr_pri_blocks=57095605_262941681_2_1_0__21200&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

address: 'Se, Funchal',

price: '1,045 lei',

ratings: '8.3Very Good 647 reviews',

thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/364430623.webp?k=8c1e510da2aad0fc9ff5731c3874e05b1c4cceec01a07ef7e9db944799771724&o=&s=1'

},

{

name: 'Les Suites at The Cliff Bay - PortoBay',

url: 'https://www.booking.com/hotel/pt/les-suites-at-the-cliff-bay.html?aid=304142&label=gen173nr-1FCAQoggJCFnNlYXJjaF9tYWRlaXJhIGlzbGFuZHNIMVgEaMABiAEBmAExuAEXyAEM2AEB6AEB-AEDiAIBqAIDuAK9luydBsACAdICJGViMWY2MmRjLWJhZmEtNGZhZC04MDAyLWQ4MmU3YjU5MTMwZtgCBeACAQ&ucfs=1&arphpl=1&checkin=2023-01-13&checkout=2023-01-15&group_adults=2&req_adults=2&no_rooms=1&group_children=0&req_children=0&hpos=3&hapos=3&sr_order=popularity&srpvid=42cc81de452009eb&srepoch=1673202494&all_sr_blocks=395012401_247460894_2_1_0&highlighted_blocks=395012401_247460894_2_1_0&matching_block_id=395012401_247460894_2_1_0&sr_pri_blocks=395012401_247460894_2_1_0__100000&tpi_r=2&from_sustainable_property_sr=1&from=searchresults#hotelTmpl',

address: 'Sao Martinho, Funchal',

price: '4,928 lei',

ratings: '9.5Exceptional 119 reviews',

thumbnails: 'https://cf.bstatic.com/xdata/images/hotel/square200/270120962.webp?k=68ded1031f5082597c48eb25c833ea7fcedc2ec2bc5d555adfcac98b232f9745&o=&s=1'

}

]

Alternativas

Aunque el tutorial hasta este punto parecía sencillo, debemos mencionar las advertencias que se suelen encontrar en el web scraping, especialmente en el caso de que quieras ampliar tu proyecto.

Hoy en día los sitios web implementan varias técnicas de detección de bots y recopilan datos del navegador para poder prevenir o bloquear el tráfico automatizado. Booking.com no es una excepción a esta regla. Utilizando la protección PerimeterX, el sitio web realiza comprobaciones de tu IP y recopila múltiple información:

  • propiedades del objeto Navigator (deviceMemory, languages, platform, userAgent, webdriver, etc.)
  • enumeración de fuentes y plugins
  • comprobación de las dimensiones de la pantalla
  • y muchos más.

Una solución a estos retos es utilizar una API de scraping, que ofrece una forma sencilla y fiable de acceder a los datos de sitios web como Booking.com sin necesidad de crear y mantener tu propio scraper.

WebScrapingAPI es un producto de este tipo, que utiliza la rotación de proxy para eludir los CAPTCHA y aleatoriza los datos del navegador para imitar a un usuario real. Para empezar, sólo tiene que registrarse para obtener una cuenta y su clave API desde el panel de control. Esta clave se utiliza para autenticar sus solicitudes.

blog-image

Para probar rápidamente la API con el proyecto Node.js ya existente, podemos hacer uso de su SDK correspondiente. Basta con ejecutar el siguiente comando:

npm install webscrapingapi

Ahora, todo lo que tiene que hacer es ajustar los selectores CSS anteriores a la API. La función de reglas de extracción te permite analizar datos con modificaciones mínimas, lo que la convierte en una potente herramienta de tu kit de herramientas de raspado web.

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage() {

const api_params = {

'render_js': 1,

'proxy_type': 'datacenter',

'timeout': 60000,

'extract_rules': JSON.stringify({

names: {

selector: 'div[data-testid="title"]',

output: 'text',

all: '1'

},

locations: {

selector: 'a[data-testid="title-link"]',

output: '@href',

all: '1'

},

addresses: {

selector: '[data-testid="address"]',

output: 'text',

all: '1'

},

prices: {

selector: '[data-testid="price-and-discounted-price"]',

output: 'text',

all: '1'

},

ratings: {

selector: '[data-testid="review-score"]',

output: 'text',

all: '1'

},

thumbnails: {

selector: '[data-testid="image"]',

output: '@src',

all: '1'

}

})

}

const URL = "https://www.booking.com/searchresults.en-us.html?ss=Madeira+Islands&checkin=2023-01-13&checkout=2023-01-15"

const response = await client.get(URL, api_params)

if (response.success) {

// Group the lists

const listings = []

for (let i = 0; i < response.response.data.names.length; i++) {

listings.push({

name: response.response.data.names[i],

url: response.response.data.locations[i],

address: response.response.data.addresses[i],

price: response.response.data.prices[i],

ratings: response.response.data.ratings[i],

thumbnails: response.response.data.thumbnails[i]

})

}

console.log(listings)

} else {

console.log(response.error.response.data)

}

}

exampleUsage();

Conclusión

En este tutorial, cubrimos los conceptos básicos de cómo raspar Booking.com usando Node.js y Puppeteer. Te mostramos cómo configurar tu entorno y extraer los detalles de los listados de Madeira, Portugal. Sin embargo, estas técnicas y conceptos también se pueden aplicar a otros sitios web y puntos de datos.

El scraping web puede ser una herramienta increíblemente útil tanto para las empresas como para los científicos de datos. Al recopilar datos de Booking.com, puedes obtener información valiosa sobre el sector hotelero, evaluar a la competencia y mucho más. Sin embargo, es importante tener en cuenta que el web scraping puede ir en contra de las condiciones de uso de algunos sitios web, y siempre es una buena idea comprobar las políticas específicas antes de proceder.

Aunque es posible crear su propio raspador web, recurrir a un servicio profesional puede ser a menudo una opción más segura y eficaz, especialmente para proyectos de mayor envergadura. Un raspador profesional tendrá la experiencia y los recursos necesarios para hacer frente a cualquier problema que pueda surgir y ofrecer resultados de alta calidad.

Esperamos que hayas disfrutado de este tutorial y que ahora te sientas equipado para recopilar datos valiosos de Booking.com utilizando un entorno Node.js. ¡Gracias por leernos!

Noticias y actualidad

Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

miniatura
GuíasTutorial de Scrapy Splash: Dominar el arte del scraping de sitios web renderizados en JavaScript con Scrapy y Splash

Aprenda a scrapear sitios web dinámicos con JavaScript utilizando Scrapy y Splash. Desde la instalación hasta la escritura de una araña, el manejo de la paginación y la gestión de las respuestas de Splash, esta completa guía ofrece instrucciones paso a paso tanto para principiantes como para expertos.

Ștefan Răcila
avatar de autor
Ștefan Răcila
6 min leer
miniatura
Casos prácticosUtilizando Web Scraping para Datos Alternativos en Finanzas: Guía completa para inversores

Explore el poder transformador del web scraping en el sector financiero. Desde datos de productos hasta análisis de opiniones, esta guía ofrece información sobre los distintos tipos de datos web disponibles para tomar decisiones de inversión.

Mihnea-Octavian Manolache
avatar de autor
Mihnea-Octavian Manolache
13 min leer
miniatura
GuíasGuía de inicio rápido de la API de Web Scraping

Empiece con WebScrapingAPI, la solución definitiva para el web scraping. Recopile datos en tiempo real, evite los sistemas anti-bot y disfrute de soporte profesional.

Mihnea-Octavian Manolache
avatar de autor
Mihnea-Octavian Manolache
9 min leer