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:
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:
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:
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 2Contornar 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.
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.




