Voltar ao blogue
Guias
Raluca Penciuc3 de março de 20238 minutos de leitura

Como fazer web scraping no Yelp.com (Atualização de 2023) - Um guia passo a passo

Como fazer web scraping no Yelp.com (Atualização de 2023) - Um guia passo a passo

Configuração do ambiente

Antes de começarmos, vamos garantir que temos as ferramentas necessárias.

Primeiro, descarregue e instale o Node.js a partir do site oficial, certificando-se de que utiliza a versão de Suporte a Longo Prazo (LTS). Isto também instalará automaticamente o Node Package Manager (NPM), que utilizaremos para instalar dependências adicionais.

Para este tutorial, iremos utilizar o Visual Studio Code como nosso Ambiente de Desenvolvimento Integrado (IDE), mas pode utilizar qualquer outro IDE à sua escolha. Crie uma nova pasta para o seu projeto, abra o terminal e execute o seguinte comando para configurar um novo projeto Node.js:

npm init -y

Isto irá criar um ficheiro package.json no diretório do seu projeto, que armazenará informações sobre o seu projeto e as suas dependências.

Em seguida, precisamos de instalar o TypeScript e as definições de tipos para o Node.js. O TypeScript oferece tipagem estática opcional, o que ajuda a evitar erros no código. Para o fazer, execute no terminal:

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

Pode verificar a instalação executando:

npx tsc --version

O TypeScript utiliza um ficheiro de configuração chamado tsconfig.json para armazenar opções do compilador e outras definições. Para criar este ficheiro no seu projeto, execute o seguinte comando:

npx tsc -init

Certifique-se de que o valor de “outDir” está definido como “dist”. Desta forma, separaremos os ficheiros TypeScript dos ficheiros compilados. Pode encontrar mais informações sobre este ficheiro e as suas propriedades na documentação oficial do TypeScript.

Agora, crie um diretório “src” no seu projeto e um novo ficheiro “index.ts”. É aqui que iremos manter o código de scraping. Para executar código TypeScript, é necessário compilá-lo primeiro; por isso, para garantir que não nos esquecemos deste passo adicional, podemos usar um comando definido por nós.

Vá até ao ficheiro “package.json” e edite a secção “scripts” da seguinte forma:

"scripts": {

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

}

Desta forma, quando executar o script, basta digitar “npm run test” no seu terminal.

Por fim, para extrair os dados do site, usaremos o Puppeteer, uma biblioteca de navegador headless para Node.js que permite controlar um navegador web e interagir com sites de forma programática. Para instalá-lo, execute este comando no terminal:

npm install puppeteer

É altamente recomendado quando se pretende garantir a integridade dos dados, uma vez que muitos sites atuais contêm conteúdo gerado dinamicamente. Se estiver curioso, pode consultar a documentação do Puppeteer antes de continuar para ver todas as suas capacidades.

Localização dos dados

Agora que já tem o seu ambiente configurado, podemos começar a ver como extrair os dados. Para este artigo, optei por fazer o scraping da página de um restaurante irlandês de Dublin: https://www.yelp.ie/biz/the-boxty-house-dublin?osq=Restaurants.

Vamos extrair os seguintes dados:

  • o nome do restaurante;
  • a classificação do restaurante;
  • o número de avaliações do restaurante;
  • o site da empresa;
  • o número de telefone do estabelecimento;
  • os endereços físicos do restaurante.

Pode ver todas estas informações destacadas na captura de ecrã abaixo:

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

Ao abrir as Ferramentas do Desenvolvedor em cada um destes elementos, poderá observar os seletores CSS que iremos utilizar para localizar os elementos HTML. Se ainda não estiver familiarizado com o funcionamento dos seletores CSS, não hesite em consultar este guia para principiantes.

Extrair os dados

Antes de escrever o nosso script, vamos verificar se a instalação do Puppeteer correu bem:

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")

Aqui, abrimos uma janela do navegador, criamos uma nova página, navegamos até ao nosso URL de destino e fechamos o navegador. Por uma questão de simplicidade e depuração visual, abro a janela do navegador maximizada no modo não headless.

Agora, vamos dar uma olhada na estrutura do site:

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

Parece que o Yelp apresenta uma estrutura de página um pouco complexa, uma vez que os nomes das classes são gerados aleatoriamente e muito poucos elementos têm valores de atributos únicos.

Mas não se preocupe, podemos ser criativos com a solução. Em primeiro lugar, para obter o nome do restaurante, selecionamos o único elemento “h1” presente na página.

// Extract restaurant name

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

    const name = document.querySelector('h1')

    return name ? name.textContent : ''

})

console.log(restaurant_name)

Agora, para obter a classificação do restaurante, pode reparar que, para além dos ícones de estrelas, o valor explícito está presente no atributo «aria-label». Assim, selecionamos o elemento «div» cujo atributo «aria-label» termina com a sequência «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)

E, finalmente (para esta secção HTML específica), vemos que podemos facilmente obter o número da avaliação selecionando o elemento âncora destacado.

// Extract restaurant reviews

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

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

    return reviews ? reviews.textContent : ''

})

console.log(restaurant_reviews)

Fácil, fácil. Vamos dar uma olhadela no widget de informações da empresa:

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

Infelizmente, nesta situação, não podemos contar com os seletores CSS. Felizmente, podemos utilizar outro método para localizar os elementos HTML: o XPath. Se ainda não tem muita familiaridade com o funcionamento dos seletores CSS, não hesite em consultar este guia para principiantes.

Para extrair o site do restaurante: aplicamos a seguinte lógica:

localizar o elemento “p” que tenha “Site da empresa” como conteúdo de texto;

localizar o elemento irmão seguinte

localizar o elemento âncora e o seu 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)

Agora, para o número de telefone e a morada, podemos seguir exatamente a mesma lógica, com duas exceções:

  • para o número de telefone, paramos no elemento irmão seguinte e extraímos a sua propriedade textContent;
  • para o endereço, selecionamos o elemento irmão seguinte do elemento pai.
// 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)

O resultado final deve ficar assim:

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

Contornar a deteção de bots

Embora o scraping do Yelp possa parecer fácil à primeira vista, o processo pode tornar-se mais complexo e desafiante à medida que o projeto cresce. O site implementa várias técnicas para detetar e impedir o tráfego automatizado, pelo que o seu scraper, à medida que cresce, começa a ser bloqueado.

O Yelp recolhe vários dados do navegador para gerar e associar-lhe uma impressão digital única. Alguns destes são:

  • propriedades do objeto Navigator (deviceMemory, hardwareConcurrency, platform, userAgent, webdriver, etc.)
  • verificações de tempo e desempenho
  • service workers
  • verificações das dimensões do ecrã
  • e muitos mais

Uma forma de superar estes desafios e continuar a fazer scraping em grande escala é utilizar uma API de scraping. Este tipo de serviços oferece uma forma simples e fiável de aceder a dados de sites como o yelp.com, sem a necessidade de criar e manter o seu próprio scraper.

A WebScrapingAPI é um exemplo desse tipo de produto. O seu mecanismo de rotação de proxies evita completamente os CAPTCHAs, e a sua base de conhecimento alargada permite randomizar os dados do navegador para que pareça um utilizador real.

A configuração é rápida e fácil. Basta registar uma conta para receber a sua chave API. Esta pode ser acedida a partir do seu painel de controlo e é utilizada para autenticar os pedidos que enviar.

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

Como já configurou o seu ambiente Node.js, podemos utilizar o SDK correspondente. Execute o seguinte comando para o adicionar às dependências do seu projeto:

npm install webscrapingapi

Agora, basta enviar uma solicitação GET para recebermos o documento HTML do site. Note que esta não é a única forma de aceder à 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();

Ao ativar o parâmetro “render_js”, enviamos a solicitação usando um navegador headless, tal como fez anteriormente neste tutorial.

Depois de receber o documento HTML, pode usar outra biblioteca para extrair os dados de interesse, como o Cheerio. Nunca ouviu falar dele? Consulte este guia para o ajudar a começar!

Conclusão

Este artigo apresentou-lhe um guia abrangente sobre como fazer web scraping no Yelp utilizando TypeScript e Puppeteer. Passámos pelo processo de configuração do ambiente, localização e extração de dados, e explicámos por que razão utilizar um scraper profissional é uma solução melhor do que criar o seu próprio.

Os dados extraídos do Yelp podem ser utilizados para diversos fins, tais como identificar tendências de mercado, analisar a opinião dos clientes, monitorizar a concorrência, criar campanhas de marketing direcionadas e muito mais.

Em geral, o web scraping do Yelp.com pode ser um recurso valioso para quem procura obter uma vantagem competitiva no seu mercado local, e este guia forneceu um excelente ponto de partida para o fazer.

Sobre o autor
Raluca Penciuc, Desenvolvedor Full-Stack @ WebScrapingAPI
Raluca PenciucDesenvolvedor Full-Stack

Raluca Penciuc é programadora Full Stack na WebScrapingAPI, onde desenvolve scrapers, aperfeiçoa estratégias de evasão e procura formas fiáveis de reduzir a deteção nos sites-alvo.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.