Skip to content

LeonamDev/generic-crawler

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 

Repository files navigation

Generic Crawler

Crawler genérico.

WORK IN PROGRESS!!!

ps: Código está sendo feito em cima dessa página: http://www.botanica.org.br/rbh-catalogo para iniciar.

O Crawler

Estou criando uma função genérica para crawlers onde eu preciso de algumas informações para que isso seja possível, basicamente elas são:

  • URL a ser buscada
  • Elemento HTML a se encontrar que contenha os outros valores
  • Path onde se encontram os valores

Porém só isso não adianta, então vamos ver o padrão que estou criando para esse projeto.

O Padrão

Vamos imaginar nossa função crawlerGeneric como deverá ser:

crawlerGeneric(BASE_URL, elementList, fields, options)

Com certeza você deve se perguntar:

WTF são esses parâmetros?

Vou explicar já já! Antes vamos ver como ficará nossa função de crawler:

const crawlerGeneric = (BASE_URL, elementList, fields, options, callback) => {
  myRequest
  .then(success)
  .catch(error)
}

mind blow

SIM! Estou usando promises, mas como?

Muito fácil! Com o módulo request-promise, ficando assim:

const rp = require('request-promise');
const cheerio = require('cheerio')

// Definimos os valores a serem achados
const elementList = '.tx_dados_herb'
const fields = [
  {
    name: '',
    value: 'this.children[0].data'
  },
  {
    name: 'Instituicao',
    value: 'this.children[0].data'
  },
  {
    name: 'Departamento',
    value: 'this.children[0].data'
  },
  {
    name: 'Endereco',
    value: 'this.children[0].data'
  },
  {
    name: 'MunicipioUF',
    value: 'this.children[0].data'
  }
]

// Definimos os valores da requisição
const BASE_URL = 'http://www.botanica.org.br/rbh-catalogo'
const optionsRequest = {
    uri: BASE_URL,
    transform: function (body) {
        return cheerio.load(body);
    }
};

// Definimos os callbacks para a Promise
const error = (err) => {
  throw new Error(err)
}
const success = ($) => {
  let Dados = []
  let obj = {}
  // Aqui pegamos todos os objetos do DOM com essa classe '.tx_dados_herb'
  $(elementList).each(function(i, element){
    // O VALOR correto vem em this.children[0].data 
    // que está em fields[i].value por isso o eval
    if(options.conditionGetValues(i)) {
      obj[fields[i].name] = eval(fields[i].value)
    }
    else if(options.conditionBreakList(i)) {
      return callback(obj)
    }
  })
}

// Definimos o options
const options = {
  conditionGetValues: (i) => i>0 && i<5,
  conditionBreakList: (i) => i >= 5
}

// Definimos o callback que executará na Promise de SUCESSO
const callback = (obj) => { 
  console.log('Dados: ', obj)
  return false // necessário para sair do EACH
}

const crawlerGeneric = (BASE_URL, elementList, fields, options, callback) => {
  rp(optionsRequest) // faz a requisição
  .then(success)
  .catch(error)
}

crawlerGeneric(BASE_URL, elementList, fields, options, callback)

Claro que irei explicar parte a parte!

TE AMO

BASE_URL

URL a ser pesquisada

elementList

Nome da classe/elemento que contém a lista dos elementos que possuem os valores desejados, por exemplo:

const elementList = '.tx_dados_herb'
// ou const elementList = 'p'

fields

Array de Objetos que mapeiam o nome que você deseja pro valor com a seleção CSS ou JS, por exemplo:

    const fields = [{
    name: 'Instituicao',
    value: 'this.children[0].data'
  }]

options

Objeto com valores e funções opcionais, por exemplo:

const options = {
  conditionGetValues: (i) => i>0 && i<5,
  conditionBreakList: (i) => i >= 5
}

callback

Generic Crawler

Aqui começamos nossa saga para a refatoração desse crawler para que ele vire um módulo externo a ser importado.

About

Cralwer genérico e maroto!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%