How to handle ERR_CONNECTION_TIMED_OUT error in webscraping using a list

0

I'm learning node.js and got with the help of @Sorack joking with a webscraping.

With respect to the code the following happens when the statusCode of the page is equal to 200 the page returns the information and generate it in the file as requested, however when it is different from 200 it presents an error in the console and for the execution. / p>

How to handle this error for example in the list of urls in case some url happens to be out of the air the script or generate a log.txt with the site or present the error message in the console but to generate the information of the other pages /

I have an impression that is related to the throw command that for execution, but I could not get around it.

const cheerio = require('cheerio');
const { get } = require('request');
const { writeFileSync } = require('fs');  
const { promisify } = require('util');
const moment = require('moment');

// Transforma o "get" em uma função que retorna uma promessa
const promisedGET = promisify(get);

const visitar = async (crc, assinatura, uri) => {
const { statusCode, body } = await promisedGET({ uri, encoding: 'binary' });

  // Retorna um erro caso o status seja diferente de 200
  if (statusCode !== 200) throw new Error(body);

   return { crc, assinatura, body };
  } 

const ler = async ({ crc, assinatura, body }) => {
const $ = cheerio.load(body);

const cliente = $('table.Class_Relatorio tr:nth-of-type(4) > td:nth-of-type(2)').text().trim();
 const versao = $('table.Class_Relatorio tr:nth-of-type(1) > td:nth-of- type(1)').text().trim();
  const lic = $('title').text().trim();
  const data = new moment().format('DD/MM/YYYY');

return { crc, assinatura, cliente, versao ,lic , data};
} 

const executar = async urls => {
 // Faz requisições para todos os sites da lista
 const paginas = await Promise.all(urls.map(({ crc, assinatura, url }) => 
visitar(crc, assinatura, url)));
// Lê as páginas retornadas e transforma em objetos
const linhas = await Promise.all(paginas.map(conteudo => ler(conteudo)));
// Transforma as linhas em uma string de conteúdo
const conteudo = linhas.map(({ crc, assinatura, cliente, versao, lic, data }) => '${crc} ; ${assinatura} ; ${cliente} ; ${versao} ; ${lic} ; ${data}').join('\n');
  // grava o conteúdo no arquivo
  writeFileSync('versao.csv', conteudo);

return conteudo;
}

// Exemplo da chamada da função principal
(async () => {
// Inicia o timer
console.time('Execução');

try {
await executar([
 {crc: '1' ,assinatura: 'ROLANDIA', url: 
'http://transparencia.rolandia.pr.gov.br/pronimtb/index.asp'},
 {crc: '2' ,assinatura: 'MATINHOS', url: 
'http://transparencia.matinhos.pr.gov.br/pronimtb/index.asp'},
 {crc: '3' ,assinatura: 'TESTE', url: 
'http://200.7.0.34/pronimtb/index.asp'},
 {crc: '4' ,assinatura: 'BOCAIUVA DO SUL', url: 
'http://transparencia.bocaiuvadosul.pr.gov.br:9191/pronimtb/index.asp'},
 {crc: '5' ,assinatura: 'CASTANHAL', url: 
'http://transparencia.castanhal.pa.gov.br/pronimtb/index.asp'}

]);


}catch (err) {
console.log(err) 
} 

// Totaliza o tempo de execução
console.timeEnd('Execução');
})();

I tried to deal with a try using this example, but I could not run it correctly.

try {
// the synchronous code that we want to catch thrown errors on
var err = new Error('example')
throw err
} catch (err) {
// handle the error safely
console.log(err)
}

This was the question, thank you:)

    
asked by anonymous 02.10.2018 / 22:12

1 answer

0

With Promise.all is all or nothing, then you will have to treat the divergent results in the ler function. I made the following changes to write a separate file for crashes and a file similar to the previous one for the successes:

const cheerio = require('cheerio');
const { get } = require('request');
const { writeFileSync } = require('fs');
const { promisify } = require('util');

// Transforma o "get" em uma função que retorna uma promessa
const promisedGET = promisify(get);

const visitar = async (crc, assinatura, uri) => {
  const { statusCode, body } = await promisedGET({ uri, encoding: 'binary' });

  return { crc, assinatura, body, statusCode };
}

const pad = (numero, tamanho) => {
  let texto = String(numero);

  while (texto.length < (tamanho || 2)) {
    texto = '0' + texto;
  }

  return texto;
}

const formatar = (data = new Date()) => {
  const dia = pad(data.getDate(), 2);
  const mes = pad(data.getMonth() + 1, 2);
  const ano = pad(data.getFullYear(), 4);

  return '${dia}/${mes}/${ano}';
}

const ler = async ({ crc, assinatura, body, statusCode }, sucesso, falhas) => {
  const data = formatar();

  if (statusCode !== 200) {
    falhas.push({ crc, assinatura, data, statusCode });
    return;
  }

  const $ = cheerio.load(body);

  const cliente = $('table.Class_Relatorio tr:nth-of-type(4) > td:nth-of-type(2)').text().trim();
  const versao = $('table.Class_Relatorio tr:nth-of-type(1) > td:nth-of-type(1)').text().trim();
  const lic = $('title').text().trim();

  sucesso.push({ crc, assinatura, cliente, versao ,lic , data});
}

const executar = async urls => {
  const sucessos = [];
  const falhas = [];
  // Faz requisições para todos os sites da lista
  const paginas = await Promise.all(urls.map(({ crc, assinatura, url }) => visitar(crc, assinatura, url)));
  // Lê as páginas retornadas
  await Promise.all(paginas.map(conteudo => ler(conteudo, sucessos, falhas)));
  // Transforma os resultados em conteúdos de arquivos
  writeFileSync('versao.csv', sucessos.map(({ crc, assinatura, cliente, versao, lic, data }) => '${crc} ; ${assinatura} ; ${cliente} ; ${versao} ; ${lic} ; ${data}').join('\n'));
  writeFileSync('falhas.csv', falhas.map(({ crc, assinatura, statusCode, data }) => '${crc} ; ${assinatura} ; ${statusCode} ; ${data}').join('\n'));
}

// Exemplo da chamada da função principal
(async () => {
  // Inicia o timer
  console.time('Execução');

  try {
    await executar([
      { crc: '1' ,assinatura: 'ROLANDIA', url: 'http://transparencia.rolandia.pr.gov.br/pronimtb/index.asp' },
      { crc: '2' ,assinatura: 'MATINHOS', url: 'http://transparencia.matinhos.pr.gov.br/pronimtb/index.asp' },
      { crc: '3' ,assinatura: 'TESTE', url: 'http://200.7.0.34/pronimtb/index.asp' },
      { crc: '4' ,assinatura: 'BOCAIUVA DO SUL', url: 'http://transparencia.bocaiuvadosul.pr.gov.br:9191/pronimtb/index.asp' },
      { crc: '5' ,assinatura: 'CASTANHAL', url: 'http://transparencia.castanhal.pa.gov.br/pronimtb/index.asp' },
    ]);
  } catch (err) {
    console.log(err)
  }

  // Totaliza o tempo de execução
  console.timeEnd('Execução');
})();
    
11.10.2018 / 15:18