Volver al blog
Guías
Raluca Penciuc3 de marzo de 20238 minutos de lectura

Cómo extraer datos de Yelp.com (Actualización de 2023): una guía paso a paso

Cómo extraer datos de Yelp.com (Actualización de 2023): una guía paso a paso

Configuración del entorno

Antes de empezar, asegurémonos de que contamos con las herramientas necesarias.

En primer lugar, descarga e instala Node.js desde la página web oficial, asegurándote de utilizar la versión de soporte a largo plazo (LTS). Esto también instalará automáticamente Node Package Manager (NPM), que utilizaremos para instalar otras dependencias.

Para este tutorial, utilizaremos Visual Studio Code como nuestro entorno de desarrollo integrado (IDE), pero puedes usar cualquier otro IDE de tu elección. Crea una nueva carpeta para tu proyecto, abre el terminal y ejecuta el siguiente comando para configurar un nuevo proyecto de Node.js:

npm init -y

Esto creará un archivo package.json en el directorio de tu proyecto, que almacenará información sobre tu proyecto y sus dependencias.

A continuación, debemos instalar TypeScript y las definiciones de tipos para Node.js. TypeScript ofrece tipado estático opcional, lo que ayuda a prevenir errores en el código. Para ello, ejecuta en la terminal:

npm install typescript @types/node --save-dev

Puedes verificar la instalación ejecutando:

npx tsc --version

TypeScript utiliza un archivo de configuración llamado tsconfig.json para almacenar las opciones del compilador y otros ajustes. Para crear este archivo en tu proyecto, ejecuta el siguiente comando:

npx tsc -init

Asegúrate de que el valor de «outDir» esté establecido en «dist». De esta forma separaremos los archivos de TypeScript de los compilados. Puedes encontrar más información sobre este archivo y sus propiedades en la documentación oficial de TypeScript.

Ahora, crea un directorio «src» en tu proyecto y un nuevo archivo «index.ts». Aquí es donde guardaremos el código de scraping. Para ejecutar código TypeScript tienes que compilarlo primero, así que, para asegurarnos de que no nos olvidamos de este paso adicional, podemos usar un comando definido por nosotros mismos.

Ve al archivo «package.json» y edita la sección «scripts» de la siguiente manera:

"scripts": {

    "test": "npx tsc && node dist/index.js"

}

De esta forma, cuando ejecutes el script, solo tendrás que escribir «npm run test» en tu terminal.

Por último, para extraer los datos del sitio web, utilizaremos Puppeteer, una biblioteca de navegador sin interfaz gráfica para Node.js que te permite controlar un navegador web e interactuar con sitios web mediante programación. Para instalarlo, ejecuta este comando en la terminal:

npm install puppeteer

Es muy recomendable si quieres asegurarte de que tus datos estén completos, ya que muchos sitios web actuales contienen contenido generado dinámicamente. Si tienes curiosidad, puedes echar un vistazo a la documentación de Puppeteer antes de continuar para ver todo lo que es capaz de hacer.

Ubicación de los datos

Ahora que ya tienes tu entorno configurado, podemos empezar a ver cómo extraer los datos. Para este artículo, he elegido extraer la página de un restaurante irlandés de Dublín: https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants.

Vamos a extraer los siguientes datos:

  • el nombre del restaurante;
  • la valoración del restaurante;
  • el número de reseñas del restaurante;
  • la página web del negocio;
  • el número de teléfono del negocio;
  • las direcciones físicas del restaurante.

Puedes ver toda esta información resaltada en la captura de pantalla siguiente:

Yelp business page with highlighted areas for the restaurant name, rating, and contact information

Al abrir las Herramientas de desarrollador en cada uno de estos elementos, podrás ver los selectores CSS que utilizaremos para localizar los elementos HTML. Si eres bastante nuevo en el funcionamiento de los selectores CSS, no dudes en consultar esta guía para principiantes.

Extracción de los datos

Antes de escribir nuestro script, comprobemos que la instalación de Puppeteer se ha realizado correctamente:

import puppeteer from 'puppeteer';

async function scrapeYelpData(yelp_url: string): Promise<void> {

    // Launch Puppeteer

    const browser = await puppeteer.launch({

        headless: false,

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

    	  defaultViewport: null

    })

    // Create a new page

    const page = await browser.newPage()

    // Navigate to the target URL

    await page.goto(yelp_url)

    // Close the browser

    await browser.close()

}

scrapeYelpData("https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants")

Aquí abrimos una ventana del navegador, creamos una nueva página, navegamos a nuestra URL de destino y cerramos el navegador. En aras de la simplicidad y la depuración visual, abro la ventana del navegador maximizada en modo no headless.

Ahora, echemos un vistazo a la estructura del sitio web:

Yelp business page with browser devtools highlighting the HTML for the listing title and star rating

Parece que Yelp presenta una estructura de página algo complicada, ya que los nombres de las clases se generan aleatoriamente y muy pocos elementos tienen valores de atributos únicos.

Pero no te preocupes, podemos ser creativos con la solución. En primer lugar, para obtener el nombre del restaurante, nos centramos en el único elemento «h1» presente en la página.

// Extract restaurant name

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

    const name = document.querySelector('h1')

    return name ? name.textContent : ''

})

console.log(restaurant_name)

Ahora, para obtener la valoración del restaurante, se puede observar que, más allá de los iconos de estrellas, el valor explícito está presente en el atributo «aria-label». Por lo tanto, nos centramos en el elemento «div» cuyo atributo «aria-label» termina con la cadena «star rating».

// Extract restaurant rating

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

    const rating = document.querySelector('div[aria-label$="star rating"]')

    return rating ? rating.getAttribute('aria-label') : ''

})

console.log(restaurant_rating)

Y, por último (para esta sección HTML en concreto), vemos que podemos obtener fácilmente el número de reseñas seleccionando el elemento de anclaje resaltado.

// Extract restaurant reviews

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

    const reviews = document.querySelector('a[href="#reviews"]')

    return reviews ? reviews.textContent : ''

})

console.log(restaurant_reviews)

Pan comido. Echemos un vistazo al widget de información de la empresa:

Yelp contact card with highlighted website URL, phone number, and directions, alongside devtools HTML view

Por desgracia, en esta situación no podemos recurrir a los selectores CSS. Por suerte, podemos utilizar otro método para localizar los elementos HTML: XPath. Si eres bastante nuevo en el funcionamiento de los selectores CSS, no dudes en consultar esta guía para principiantes.

Para extraer la página web del restaurante, aplicamos la siguiente lógica:

localizar el elemento «p» que tiene «Sitio web de la empresa» como contenido de texto;

localizar el siguiente elemento hermano

localizar el elemento de anclaje y su atributo «href».

// Extract restaurant website

const restaurant_website_element = await page.$x("//p[contains(text(), 'Business website')]/following-sibling::p/a/@href")

const restaurant_website = await page.evaluate(

    element => element.nodeValue,

    restaurant_website_element[0]

)

console.log(restaurant_website)

Ahora, para el número de teléfono y la dirección podemos seguir exactamente la misma lógica, con dos excepciones:

  • para el número de teléfono, nos detenemos en el elemento hermano siguiente y extraemos su propiedad textContent;
  • para la dirección, nos centramos en el elemento hermano siguiente del elemento padre.
// Extract restaurant phone number

const restaurant_phone_element = await page.$x("//p[contains(text(), 'Phone number')]/following-sibling::p")

const restaurant_phone = await page.evaluate(

    element => element.textContent,

    restaurant_phone_element[0]

)

console.log(restaurant_phone)

// Extract restaurant address

const restaurant_address_element = await page.$x("//a[contains(text(), 'Get Directions')]/parent::p/following-sibling::p")

const restaurant_address = await page.evaluate(

    element => element.textContent,

    restaurant_address_element[0]

)

console.log(restaurant_address)

El resultado final debería ser así:

The Boxty House

4.5 star rating

948 reviews

/biz_redir?url=http%3A%2F%2Fwww.boxtyhouse.ie%2F&cachebuster=1673542348&website_link_type=website&src_bizid=EoMjdtjMgm3sTv7dwmfHsg&s=16fbda8bbdc467c9f3896a2dcab12f2387c27793c70f0b739f349828e3eeecc3

(01) 677 2762

20-21 Temple Bar Dublin 2

Evitar la detección de bots

Aunque extraer datos de Yelp puede parecer fácil al principio, el proceso puede volverse más complejo y desafiante a medida que amplías tu proyecto. El sitio web implementa diversas técnicas para detectar y prevenir el tráfico automatizado, por lo que tu extractor ampliado empieza a ser bloqueado.

Yelp recopila múltiples datos del navegador para generar y asociarte una huella digital única. Algunos de ellos son:

  • propiedades del objeto Navigator (deviceMemory, hardwareConcurrency, platform, userAgent, webdriver, etc.)
  • comprobaciones de tiempo y rendimiento
  • servicios de fondo
  • comprobaciones de las dimensiones de la pantalla
  • y muchos más

Una forma de superar estos retos y seguir realizando scraping a gran escala es utilizar una API de scraping. Este tipo de servicios ofrecen una forma sencilla y fiable de acceder a datos de sitios web como yelp.com, sin necesidad de crear y mantener tu propio scraper.

WebScrapingAPI es un ejemplo de este tipo de productos. Su mecanismo de rotación de proxies evita por completo los CAPTCHA, y su amplia base de conocimientos permite aleatorizar los datos del navegador para que parezca un usuario real.

La configuración es rápida y sencilla. Solo tienes que registrarte para obtener tu clave API. Puedes acceder a ella desde tu panel de control y se utiliza para autenticar las solicitudes que envías.

Dashboard quickstart guide showing three steps: API access key, API Playground, and integration into your application

Como ya has configurado tu entorno Node.js, podemos utilizar el SDK correspondiente. Ejecuta el siguiente comando para añadirlo a las dependencias de tu proyecto:

npm install webscrapingapi

Ahora solo queda enviar una solicitud GET para recibir el documento HTML del sitio web. Ten en cuenta que esta no es la única forma de acceder a la API.

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage() {

    const api_params = {

        'render_js': 1,

    	  'proxy_type': 'residential',

    }

    const URL = "https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants"

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

    if (response.success) {

        console.log(response.response.data)

    } else {

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

    }

}

exampleUsage();

Al habilitar el parámetro «render_js», enviamos la solicitud utilizando un navegador sin interfaz gráfica, tal y como hiciste anteriormente en este tutorial.

Tras recibir el documento HTML, puedes utilizar otra biblioteca para extraer los datos que te interesen, como Cheerio. ¿No la conoces? ¡Echa un vistazo a esta guía para ayudarte a empezar!

Conclusión

Este artículo te ha presentado una guía completa sobre cómo realizar web scraping en Yelp utilizando TypeScript y Puppeteer. Hemos repasado el proceso de configuración del entorno, la localización y extracción de datos, y por qué utilizar un scraper profesional es una solución mejor que crear uno propio.

Los datos extraídos de Yelp se pueden utilizar para diversos fines, como identificar tendencias de mercado, analizar la opinión de los clientes, supervisar a la competencia, crear campañas de marketing dirigidas y mucho más.

En general, el web scraping de Yelp.com puede ser un activo valioso para cualquiera que busque obtener una ventaja competitiva en su mercado local, y esta guía ha proporcionado un excelente punto de partida para hacerlo.

Acerca del autor
Raluca Penciuc, Desarrollador full-stack @ WebScrapingAPI
Raluca PenciucDesarrollador full-stack

Raluca Penciuc es desarrolladora full stack en WebScrapingAPI, donde se dedica a crear rastreadores, mejorar las técnicas de evasión y buscar formas fiables de reducir la detección en los sitios web de destino.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.