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

Como fazer Web Scrape do Yelp.com (Atualização de 2023) - Um guia passo-a-passo

Como fazer Web Scrape do Yelp.com (Atualização de 2023) - Um guia passo-a-passo

Configuração do ambiente

Antes de começarmos, vamos assegurar-nos de que dispomos das ferramentas necessárias.

Primeiro, baixe e instale o Node.js do site oficial, certificando-se de usar a versão Long-Term Support (LTS). Isso também instalará automaticamente o Node Package Manager (NPM), que usaremos para instalar outras dependências.

Para este tutorial, usaremos o Visual Studio Code como nosso ambiente de desenvolvimento integrado (IDE), mas você pode usar qualquer outro IDE de sua escolha. Crie uma nova pasta para seu projeto, abra o terminal e execute o seguinte comando para configurar um novo projeto Node.js:

npm init -y

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

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

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

Pode verificar a instalação executando:

npx tsc --versão

O TypeScript usa um arquivo de configuração chamado tsconfig.json para armazenar opções do compilador e outras configurações. Para criar esse arquivo em seu projeto, execute o seguinte comando:

npx tsc -init

Certifique-se de que o valor de "outDir" esteja definido como "dist". Desta forma, iremos separar 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 vamos manter o código de raspagem. Para executar o código TypeScript, é necessário compilá-lo primeiro, portanto, para garantir que não nos esqueçamos dessa etapa extra, podemos usar um comando definido de forma personalizada.

Vá ao ficheiro "package. json" e edite a secção "scripts" desta forma:

"scripts": {

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

}

Desta forma, quando for 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 sem cabeça para Node.js que permite controlar um navegador da Web e interagir com sites de forma programática. Para instalá-la, execute este comando no terminal:

npm install puppeteer

É altamente recomendado quando se pretende garantir a integridade dos dados, uma vez que muitos sítios Web actuais contêm conteúdo gerado dinamicamente. Se estiver curioso, pode consultar a documentação do Puppeteer antes de continuar para ver o que ele é capaz de fazer.

Localização dos dados

Agora que já tem o seu ambiente configurado, podemos começar a analisar a extração dos dados. Para este artigo, optei por extrair a 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 críticas do restaurante;
  • o sítio Web da empresa;
  • o número de telefone da empresa;
  • os endereços físicos dos restaurantes.

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

Página de empresa no Yelp com áreas destacadas para o nome do restaurante, classificação e informações de contacto

Ao abrir as Ferramentas do desenvolvedor em cada um desses elementos, você poderá observar os seletores CSS que usaremos para localizar os elementos HTML. Se não sabe muito bem como funcionam os selectores CSS, pode 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é o 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 sem cabeça.

Agora, vamos dar uma vista de olhos à estrutura do sítio Web:

Página de empresa no Yelp com as ferramentas de desenvolvimento do navegador a destacar o código HTML do título do anúncio e da classificação por estrelas

Parece que o Yelp apresenta uma estrutura de página algo difícil, 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, seleccionamos 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, seleccionamos o elemento "div" cujo atributo "aria-label" termina com a cadeia "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 em particular), vemos que podemos obter facilmente o número da revisão, apontando para 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. Vejamos o widget de informações comerciais:

Cartão de contacto do Yelp com o URL do site, o número de telefone e as direções destacados, juntamente com a visualização HTML das ferramentas de desenvolvimento

Infelizmente, nesta situação, não podemos confiar nos selectores CSS. Felizmente, podemos utilizar outro método para localizar os elementos HTML: XPath. Se não sabe muito bem como funcionam os selectores CSS, não hesite em consultar este guia para principiantes.

Para extrair o sítio Web do restaurante: aplicamos a seguinte lógica:

localize o elemento "p" que tem "Business website" como conteúdo de texto;

localizar o seguinte irmão

localizar o elemento de ancoragem 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 o endereço, podemos seguir exatamente a mesma lógica, com duas excepções:

  • para o número de telefone, paramos o irmão seguinte e extraímos a sua propriedade textContent ;
  • para o endereço, visamos o seguinte irmão 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 ser o seguinte:

The Boxty House

Classificação de 4,5 estrelas

948 avaliações

/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 no início, o processo pode tornar-se mais complexo e desafiante à medida que aumenta a escala do seu projeto. O sítio Web implementa várias técnicas para detetar e impedir o tráfego automatizado, pelo que o seu scraper em grande escala começa a ser bloqueado.

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

  • propriedades do objeto Navigator (deviceMemory, hardwareConcurrency, plataforma, userAgent, webdriver, etc.)
  • controlos de prazos e de desempenho
  • trabalhadores dos serviços
  • controlo das dimensões do ecrã
  • e muitos mais

Uma forma de ultrapassar estes desafios e continuar a fazer scraping em grande escala é utilizar uma API de scraping. Estes tipos de serviços fornecem uma forma simples e fiável de aceder a dados de sítios Web como o yelp.com, sem a necessidade de construir e manter o seu próprio raspador.

O WebScrapingAPI é um exemplo de um produto deste género. O seu mecanismo de rotação de proxy evita completamente os CAPTCHAs, e a sua base de conhecimentos alargada permite aleatorizar os dados do browser para que se pareça com um utilizador real.

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

Guia de início rápido do painel de controlo, apresentando três passos: chave de acesso à API, API Playground e integração na sua aplicação

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 só falta enviar um pedido GET para recebermos o documento HTML do sítio Web. Note-se 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 o pedido utilizando um browser sem cabeça, tal como fez anteriormente ao longo deste tutorial.

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

Conclusão

Este artigo apresentou um guia abrangente sobre como fazer o web scrape do Yelp usando TypeScript e Puppeteer. Passamos pelo processo de configuração do ambiente, localização e extração de dados, e por que usar um raspador profissional é uma solução melhor do que criar o seu próprio.

Os dados extraídos do Yelp podem ser utilizados para vários fins, como a identificação de tendências de mercado, a análise do sentimento dos clientes, a monitorização da concorrência, a criação de campanhas de marketing direcionadas e muito mais.

Em geral, a recolha de dados do Yelp.com na Web pode ser um recurso valioso para quem pretende 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, Desenvolvedora Full-Stack na 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.