Automatizando o chrome com Node.js para zoar amigos
April 27, 2020
Estava revisitando meus repositórios antigos no github e achei um projeto de mais de um ano atrás, onde, eu configurava uma postagem alvo no facebook, meu usuário e senha e com isso fazia um monte de comentários no mesmo.
A gente não usa tanto facebook porem leia até o final, as vezes consegue ter uma ideia legal a partir dessa.
O que vamos fazer hoje:
Controlando o Chrome com puppeteer
Puppeteer é uma lib open source criada pelo google que disponibiliza uma série de métodos para controle do chrome de forma automatizada, clicks, execução de scripts no console do browser, prints-screens, downloads entre outros. Quase tudo que um usuário faz, porem de forma programática com Node.js.
Criando o script
I - Instalando a dependência, puppeteer x puppeteer-core
O jeito mais fácil e simples é instalando o puppeteer, conforme o código abaixo.
npm add puppeteer
Existe outra opção de instalação: puppeteer-core. Qual a diferença?
Se você instalar o puppeteer da forma simples, junto com os códigos será baixado uma versão do chrome para sua node_modules também.
No puppeteer-core você consegue informar um browser que já existe na sua máquina.
Eu geralmente faço a instalação normal pela comodidade.
II - Instanciando o browser
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch({
headless: false,
args: ['--disable-notifications']
})
Opções passadas no launch:
headless
:
Define se o puppeteer vai abrir a interface gráfica do browser quando for executar o script, por padrão essa opção é true, ou seja, a interface não é aberta. Eu gosto de deixar false para ver a magia acontecendo.args
:
Com essa opção você consegue enviar argumentos mais específicos para o chrome. Nesse caso estou passado apenas--disable-notifications
, para bloquear as notificações do browser, que estavam travando o proceso.
II - Navegando até o POST
const page = await browser.newPage()
Cria uma “nova aba” no browser e retorna um objeto do tipo Page.
await page.goto(config.FACEBOOK.POST_URL)
Navega até a página informada. Nesse caso estou importando essa variavel de config de outro arquivo, mas é bem simples.
// config.js
const config = {
COMMENTS_LIMIT: process.env.COMMENTS_LIMIT,
FACEBOOK: {
USER_NAME: process.env.USER_NAME,
PASSWORD: process.env.PASSWORD,
POST_URL: process.env.POST_URL,
COMMENT_TEXT: process.env.COMMENT_TEXT
}
}
⚠️⚠️⚠️ USE VARIAVEIS DE AMBIENTE PARA EVITAR COMITAR SUA SENHA SEM QUERER ⚠️⚠️⚠️
await page.type('#email', config.FACEBOOK.USER_NAME)
await page.type('#pass', config.FACEBOOK.PASSWORD)
await page.click('#loginbutton')
Digita login, senha e clica no botão de login. A função page.type recebe um selector e o texto que você quer digitar naquele input. A função de page.click segue a mesma lógica.
III - Escrevendo os comentários
await page.click('[contenteditable]')
Clica naquela caixa de comentários:
E a parte final:
for (let index = 0; index < config.COMMENTS_LIMIT; index++) {
await page.keyboard.type(
config.FACEBOOK.COMMENT_TEXT,
{ delay: 30 }
)
await page.keyboard.press('Enter')
await page.waitFor(1000)
}
Faz um loop besta usando a função page.keyboard.type para simular um teclado.
Porque não usei o page.type nesse caso?
Eu não entendo como funcionam esses reactos do facebook, mas toda hora o campo fica com um id diferente, então foi mais fácil simular o click na caixa de comentários e depois usar o page.keyboard.
Usei a opção de delay { delay: 30 }
para que fica-se mais parecido com um usuário real digitando, não tenho muita pressa nesse caso já que, se fizer os comentários sem uma pausa, o facebook te bloqueia por um tempo.
Resultado final
Se tiver algum feedback ou conseguir construir algo legal à partir disso, por favor me chame no twitter twitter ou telegram.
Obrigado por ler até o final. Um salve pro Marcel que me apresentou essa ferramenta muito tempo atrás.