Como criar um raspador e enviar um formulário com o Puppeteer

Mihnea-Octavian Manolache em 28 de fevereiro de 2023

imagem do blogue

Já alguma vez teve de trabalhar com pedidos POST durante a recolha de dados da Web? Tenho a certeza que sim! E é com formulários que temos que lidar na maioria das vezes. É por isso que hoje vou falar sobre como submeter o formulário com o Puppeteer. Se ainda não sabe o que é o Puppeteer, não se preocupe. Vai ficar a saber daqui a pouco. Até lá, deixe-me definir algumas expectativas para o artigo de hoje. Se você me seguir em nosso caminho de aprendizado, hoje você deve ser capaz de aprender:

  • O que é o Puppeteer na recolha de dados da Web
  • Como configurar um projeto Puppeteer simples
  • Como é que o envio de formulários é tratado no Puppeteer

Então, sem mais demoras, vamos a isso!

O que é o Puppeteer e porque é que é importante para a recolha de dados da Web?

Em geral, a raspagem da Web refere-se ao processo de automatização da extração de dados de vários servidores. Antigamente, um simples cliente HTTP teria sido suficiente para efetuar esta tarefa. Hoje em dia, porém, os sítios Web dependem cada vez mais do JavaScript. E os clientes HTTP tradicionais não são capazes de renderizar ficheiros JavaScript. É aí que o Puppeteer entra em ação.

Puppeteer é uma biblioteca Node.js que permite controlar um navegador Chrome ou Chromium sem cabeça através do protocolo DevTools. Resumindo, ela fornece uma API de alto nível para automatizar o Chrome.

Em termos de raspagem da Web, o Puppeteer é útil para raspar sites que exigem JavaScript para serem renderizados. Além disso, ele também pode ser usado para interagir com páginas da Web de forma semelhante a um ser humano. Por exemplo, clicar em botões ou o nosso foco de hoje, preencher formulários. Isso o torna ideal para raspar sites que usam técnicas anti-raspagem.

Configurar um projeto Puppeteer simples

Acredito em ir devagar para entender melhor o processo geral. Antes de entrar em como enviar o formulário com o Puppeteer, vamos falar sobre o Puppeteer simples. Nesta seção, vou mostrar como configurar um projeto Node, instalar o Puppeteer e usá-lo para extrair dados. Então, em primeiro lugar, vamos criar uma nova pasta e abri-la dentro do IDE desejado. Eu prefiro o Visual Studio Code, mas fique à vontade para usar o que quiser.

Sabia que?

  • Você pode criar 'programaticamente' uma nova pasta a partir do seu terminal digitando o comando `mkdir`.
  • É possível usar o comando `npm init -y` para configurar um projeto node e aceitar valores padrão
  • É possível criar um novo ficheiro com o comando `touch`.
  • E também pode abrir o VSCode com o comando `code .`.

Se quiser, pode combinar os quatro e criar um projeto em segundos como este:

~ " mkdir scraper && cd scraper && npm init -y && code . 

Dentro do seu IDE, abra um novo terminal (Terminal > Novo Terminal) e vamos instalar o Puppeteer. Digite `npm i puppeteer --save` dentro do seu terminal. Além disso, eu gosto de usar módulos JS em vez de CommonJS. Veja as diferenças entre os dois aqui. Se você quiser usar módulos também, abra o arquivo `package. json` e adicione `"type": "module"` ao objeto JSON.

imagem do blogue

Agora que estamos todos configurados, podemos começar a adicionar algum código. Crie um novo arquivo `index.js` e abra-o no IDE. Não é necessário fazê-lo a partir do terminal desta vez, mas apenas como uma dica, você poderia usar o comando `touch`. Agora vamos adicionar o código:

import puppeteer, { executablePath } from 'puppeteer'

const scraper = async (url) => {

const browser = await puppeteer.launch({

headless: false,

executablePath: executablePath(),

})

const page = await browser.newPage()

await page.goto(url)

const html = await page.content()

await browser.close()

return html

}

E vamos ver o que estamos a fazer:

  1. Estamos a importar o Puppeteer e o `executablePath` para o nosso projeto
  2. Estamos a definir uma nova função, que recebe um parâmetro `url`
  3. Estamos lançando um novo navegador usando `puppeteer.launch`
    a. Estamos especificando que queremos que ele execute headfull
    b. Estamos usando `executablePath` para obter o caminho do Chrome
  4. Estamos a abrir uma nova página e a navegar para o `url`
  5. Estamos a guardar o `page.content()` numa constante
  6. Fechámos a instância do navegador
  7. E, finalmente, estamos retornando a saída `html` da página que acabamos de extrair

Até agora as coisas não estão complicadas. Este é o mínimo de uma implementação de web scraper com Node JS e Puppeteer. Se você quiser executar o código, simplesmente dê à função `scraper` um alvo e registre seu valor de retorno:

consola.log(await scraper('https://webscrapingapi.com/'))

Mas lembre-se que o nosso objetivo é extrair dados ao submeter um formulário. Isso significa que temos que pensar em uma maneira de enviar o formulário com o Puppeteer. Felizmente, eu já fiz isso antes e sei que não é difícil. Então vamos ver como você pode fazer isso também.

Como enviar formulários com o Puppeteer

Pense no Puppeteer como o meio de imitar o comportamento humano num determinado sítio Web. Como é que nós, humanos, submetemos formulários? Bem, identificamos o formulário, preenchemo-lo e, normalmente, clicamos num botão. Essa é a mesma lógica usada para enviar formulários com o Titereiro. A única diferença é a forma como executamos estas acções. Porque os humanos dependem dos sentidos. Uma vez que o titereiro é um software, fá-lo-emos de forma programática, utilizando os métodos incorporados do titereiro, da seguinte forma:

#1: Enviar formulários simples com o Puppeteer

Antes de mais, precisamos de "visualizar" o nosso formulário. Num sítio Web, todos os elementos são agrupados num bloco HTML e cada elemento tem um identificador. Os identificadores consistem normalmente nos atributos CSS do elemento. No entanto, pode deparar-se com sítios Web que não têm esses selectores. Nesses casos, pode utilizar xPaths, por exemplo. Mas esse é um assunto para outra conversa. Vamos concentrar-nos na identificação de elementos no Puppeteer utilizando CSS.

Para ter algum tipo de contexto, digamos que queremos automatizar a ação de início de sessão no Stack Overflow. Portanto, o alvo é https://stackoverflow.com/users/login. Abra o navegador, navegue até a página de login e abra Ferramentas do desenvolvedor. Você pode clicar com o botão direito do mouse na página e selecionar "Inspecionar". Você deve ver algo como isto:

imagem do blogue

No lado esquerdo, existe uma interface gráfica. No lado direito, encontra-se a estrutura HTML. Se olhar com atenção para o lado direito, verá o nosso formulário. É constituído principalmente por dois inputs e um botão. Estes são os três elementos que estamos a selecionar. E, como pode ver, todos os três elementos têm um `id` como identificador CSS. Vamos traduzir o que aprendemos até agora em código:

import puppeteer, { executablePath } from 'puppeteer'

const scraper = async (target) => {

const browser = await puppeteer.launch({

headless: false,

executablePath: executablePath(),

})

const page = await browser.newPage()

await page.goto(target.url,{waitUntil: 'networkidle0'})

await page.type(target.username.selector, target.username.value)

await page.type(target.password.selector, target.password.value)

await page.click(target.buttonSelector)

const html = await page.content()

await browser.close()

return html

}

Para o manter funcional e reutilizável, optei por substituir o parâmetro da minha função por um objeto. Este objeto consiste no URL de destino, nos selectores e valores de entrada, e no seletor para o botão de submissão. Assim, para executar o código, basta criar um novo objeto `TARGET` que contenha os seus dados, e passá-lo para a sua função `scraper`:

const TARGET = {

url: 'https://stackoverflow.com/users/login',

username: {

selector: 'input[id=email]',

value: '<YOUR_USERNAME>'

},

password: {

selector: 'input[id=password]',

value: '<YOUR_PASSWORD>'

},

buttonSelector: 'button[id=submit-button]'

}

console.log(await scraper(TARGET))

#2: Carregar ficheiros com o Puppeteer

Às vezes, a automação da web exige que façamos upload de arquivos, em vez de enviar formulários simples. Se você se deparar com uma tarefa desse tipo e precisar anexar arquivos antes de enviar o formulário com o Puppeteer, você vai querer usar o método `uploadFile` do Puppeteer. Para manter as coisas simples, sugiro que você crie uma nova função para esta ação:

const upload = async (target) => {

const browser = await puppeteer.launch({

headless: false,

executablePath: executablePath(),

})

const page = await browser.newPage()

await page.goto(target.url,{waitUntil: 'networkidle0'})

const upload = await page.$(target.form.file)

await upload.uploadFile(target.file);

await page.click(target.form.submit)



await browser.close()

}

Veja como desta vez estou utilizando `page.$` para primeiro identificar o elemento. E só depois disso, estou chamando o método `uploadFile` que só funciona com os tipos `ElementHandle`. Quanto aos parâmetros, assim como anteriormente, estou usando um objeto para passar todos os dados de uma vez para a minha função. Se você quiser testar o script, basta adicionar o seguinte código e executar `node index.js` no seu terminal:

const TARGET = {

url: 'https://ps.uci.edu/~franklin/doc/file_upload.html',

form: {

file: 'input[type=file]',

submit: 'input[type=submit]'

} ,

file: './package.json'

}

upload(TARGET)

Conclusões

Resumindo, eu diria que é muito fácil enviar o formulário com o Puppeteer. Além disso, acho que, em comparação com as suas alternativas, o Puppeteer trata totalmente desta ação. Basicamente, tudo o que o utilizador tem de fazer é identificar corretamente os elementos.

Agora, devo notar que um scraper do mundo real requer muito mais para ser eficiente. Na maioria das vezes, se "abusar" de um servidor, submetendo demasiados formulários num curto período de tempo, é provável que seja bloqueado. É por isso que, se quiser automatizar o processo de envio de formulários, recomendo a utilização de um serviço de raspagem profissional. Na API de Web Scraping, oferecemos a opção de enviar pedidos POST e PUT. Pode ler mais sobre isso na nossa documentação.

Notícias e actualizações

Mantenha-se atualizado com os mais recentes guias e notícias sobre raspagem da Web, subscrevendo a nossa newsletter.

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

Artigos relacionados

miniatura
GuiasComo construir um raspador e descarregar um ficheiro com o Puppeteer

Descubra 3 formas de descarregar ficheiros com o Puppeteer e construa um web scraper que faz exatamente isso.

Mihnea-Octavian Manolache
avatar do autor
Mihnea-Octavian Manolache
8 min. de leitura
miniatura
GuiasDescubra como extrair tabelas HTML com Golang

Aprenda a raspar tabelas HTML com Golang para uma poderosa extração de dados. Explore a estrutura das tabelas HTML e crie um raspador da Web usando a simplicidade, a simultaneidade e a robusta biblioteca padrão do Golang.

Andrei Ogiolan
avatar do autor
Andrei Ogiolan
8 min. de leitura
miniatura
GuiasO melhor guia de raspagem e automação da Web para 2023

Saiba como usar o Playwright para raspagem e automação da Web com nosso guia abrangente. Desde a configuração básica até técnicas avançadas, este guia cobre tudo.

Suciu Dan
avatar do autor
Suciu Dan
16 min leitura