Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web Scraping com Chrome Headless, Puppeteer e R...

Web Scraping com Chrome Headless, Puppeteer e Ramda

Web scraping é uma técnica de extração de dados de sites da web. Ela é bastante útil pois permite a obtenção de dados de forma automatizada de sites que não fornecem uma API oficial. Nesta palestra veremos como podemos utilizar o Chrome Headless (uma forma de executar o Chrome de maneira automatizada e sem interface gráfica), o Puppeter (uma biblioteca de automatização do Chrome) e a Ramda.js (uma biblioteca de JavaScript com foco em programação funcional) para realizar a tarefa de extração de dados de sites de forma automatizada.

Avatar for Marcel dos Santos

Marcel dos Santos

November 17, 2018
Tweet

More Decks by Marcel dos Santos

Other Decks in Programming

Transcript

  1. copiar e colar informações de um site manualmente em um

    documento de texto ou planilha não parece ser a melhor solução!
  2. a não ser que a tarefa seja realmente simples e

    que dificilmente será repetida
  3. os dados são organizados e armazenados em um banco de

    dados ou em arquivos CSV, XML ou JSON
  4. a extração de dados é feita por robôs que podem

    ser implementados em qualquer tecnologia
  5. a técnica deve ser utilizada com cautela de modo a

    evitar qualquer comportamento indesejado no serviço terceiro
  6. é uma maneira de rodar o Chrome em um ambiente

    headless, ou seja, sem a interface de usuário
  7. é possível realizar o debug remoto de uma instância headless

    utilizando o DevTools Protocol a partir de outro navegador
  8. o uso via linha de comando é bastante flexível mas,

    para casos mais elaborados, recomenda-se um biblioteca de alto nível
  9. é uma biblioteca para Node que fornece uma API de

    alto nível para controlar o Chrome ou Chromium através do DevTools Protocol
  10. o Puppeteer roda de forma headless por padrão, mas pode

    ser configurado para ser executado de forma non-headless
  11. ao instalar o Puppeteer é feito o download da versão

    mais recente do Chromium para garantir o funcionamento com a API
  12. o puppeteer-core é uma versão leve para executar um browser

    já instalado ou para se conectar em um browser remoto
  13. o Puppeteer requer o Node versão 6.4.0 ou superior e,

    para utilizar async/await, a versão 7.6.0 ou superior
  14. const puppeteer = require('puppeteer'); !// 01 - launch headless chrome

    instance !// and get browser's version (async () !=> { const browser = await puppeteer.launch(); console.log(await browser.version()); await browser.close(); })();
  15. const puppeteer = require('puppeteer'); !// 02 - launch headless chrome

    instance, create new page, !// navigate to google.com.br and get pages' title (async () !=> { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https:!//google.com.br/'); console.log(await page.title()); await browser.close(); })();
  16. const puppeteer = require('puppeteer'); !// 03 - navigate to google.com.br,

    type a search term, !// wait for the result and take a screenshot (async () !=> { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https:!//!!www.google.com.br/'); await page.focus('[name="q"]'); await page.keyboard.type('devfest maceió'); await page.waitFor(2000); await page.screenshot({ path: 'devfest-maceio-search.png' }); await browser.close(); })();
  17. uma biblioteca construída para o estilo de programação funcional que

    facilita a utilização de pipelines e dados imutáveis
  18. !// shopping cart const cart = [ {id: 1, product:

    'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them
 !// using intermediate values const cartPrices = R.map(item !=> item.price, cart); const cartSum = R.sum(cartPrices); console.log(cartSum); !// 1877 realiza o mapeamento da lista de produtos (objetos) para uma lista de preços (números) faz a somatória da lista de números e retorna o total Passo 1
  19. !// shopping cart const cart = [ {id: 1, product:

    'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them
 !// using function composition const totalCart = R.compose( R.sum, R.map(item !=> item.price), ); console.log(totalCart(cart)); !// 1877 cria uma nova função a partir da composição de funções e elimina valores intermediários Passo 2 aplicação parcial da função map a composição é feita da direita para a esquerda
  20. !// shopping cart const cart = [ {id: 1, product:

    'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them !// using function composition with pipe const totalCart = R.pipe( R.map(item !=> item.price), R.sum, ); console.log(totalCart(cart)); !// 1877 Passo 3 o pipe de funções é feito da esquerda para a direita e facilita a leitura do código
  21. const puppeteer = require('puppeteer'); (async () !=> { !// 1.

    open a headless chrome instance const browser = await puppeteer.launch({ headless: false, devtools: true }); !// !!... })();
  22. const puppeteer = require('puppeteer'); (async () !=> { !// 1.

    open a headless chrome instance !// !!... !// 2. create a new page and navigate to devfest schedule const page = await browser.newPage(); await page.goto('https:!//devfest.gdgmaceio.org/programacao'); await page.waitFor(5000); !// !!... })();
  23. !// 3. get the number of stores from the report

    const list = await page.evaluate(() !=> { !// 3.1. list of time slots let listOfSlots = document.querySelectorAll('.turn-list > .item’); let talks = []; !// 3.2. iterate over each time slot listOfSlots.forEach(slot !=> { let time = slot.querySelector('.hour').innerText; !// 3.3. list of talks let listOfTalks = slot.querySelectorAll('.events-list > .item'); !// 3.4. iterate over each talk listOfTalks.forEach(talk !=> { let location = talk.querySelector('.location').innerText; let title = talk.querySelector('.title').innerText; let speaker = talk.querySelector('.speaker .name').innerText; let position = talk.querySelector('.speaker .description').innerText; let category = talk.querySelector('.category').innerText; talks.push({location, time, title, speaker, position, category}); }); }); return talks; });
  24. (async () !=> { !// 1. open a headless chrome

    instance const browser = await puppeteer.launch({ headless: false, devtools: true }); !// 2. create a new page and navigate to devfest schedule const page = await browser.newPage(); await page.goto('https:!//devfest.gdgmaceio.org/programacao'); await page.waitFor(5000); !// !!... !// 4. show scraped data console.log(list); !// 5. close browser instance await browser.close(); })();