Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adicione o Cadastro Nacional de Cursos e Instituições de Educação Superior Cadastro e-MEC #2

Open
insinfo opened this issue Aug 2, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@insinfo
Copy link

insinfo commented Aug 2, 2024

adicione o Cadastro Nacional de Cursos e Instituições de Educação Superior Cadastro e-MEC
https://emec.mec.gov.br/emec/nova

@insinfo
Copy link
Author

insinfo commented Aug 2, 2024

@GusFurtado GusFurtado added the enhancement New feature or request label Aug 3, 2024
@GusFurtado
Copy link
Owner

Obrigado pela sugestão.

Não conheço os sistemas do MEC, mas irei avaliar assim que possível.

@insinfo
Copy link
Author

insinfo commented Aug 3, 2024

criei um script em dart para baixar os dados do SISTEC

import 'dart:convert' as convert;
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';

const listaEstadosUrl =
    'https://sistec.mec.gov.br/accordionrelatoriopublico/retornaufs';
const listaCidadesUrl =
    'https://sistec.mec.gov.br/accordionrelatoriopublico/retornamunicipiosuesporuf/sguf/';
const listaUnidadesUrl =
    'https://sistec.mec.gov.br/accordionrelatoriopublico/retornauepormunicipio/municipio/';
const listaCursosUrl =
    'https://sistec.mec.gov.br/gridrelatoriopublico/gridcursosporue/ue/';

dynamic jsonDecode(String source,
    {Object? reviver(Object? key, Object? value)?}) {
  try {
    return convert.json.decode(source, reviver: reviver);
  } catch (e, s) {
    print('jsonDecode error $e $s');
    return null;
  }
}

Future<http.Response?> fetchData(String url) async {
  final client = RetryClient(http.Client());
  try {
    return await client.post(Uri.parse(url)).timeout(Duration(seconds: 30));
  } catch (e, s) {
    print('fetchData error $e $s | url $url');
    return null;
  } finally {
    client.close();
  }
}

void main(List<String> args) async {
  var file = File('cursos_tecnicos_mec_sistec.json');
  await file.writeAsString('[');
  var url = listaEstadosUrl;
  var resp = await fetchData(url);
  if (resp == null) {
    print('main error resp: $url');
  }
  var json = jsonDecode(resp!.body);
  if (json == null) {
    print('main error json: $json');
  }
  var estados = json['accordion'];
  final regExp1 = RegExp(r'"([A-Z]{2})"');
  final regExp2 = RegExp(r'"(\d+)"');
  //final listaCursos = <Curso>[];
  var count = 0;

  try {
    for (var estado in estados) {
      var acao = estado['titulo']['acao'];
      var nomeUf = estado['titulo']['html'];
      var siglaUf = regExp1.firstMatch(acao)?.group(1);
      if (siglaUf != null) {
        url = listaCidadesUrl + siglaUf;
        resp = await fetchData(url);
        if (resp != null) {
          json = jsonDecode(resp.body);
          if (json != null) {
            var municipios = json['accordion'];

            for (var municipio in municipios) {
              acao = municipio['titulo']['acao'];
              var nomeMunicipio = municipio['titulo']['html'];
              var codMunicipio = regExp2.firstMatch(acao)?.group(1);
              if (codMunicipio != null) {
                url = listaUnidadesUrl + codMunicipio;
                resp = await fetchData(url);
                if (resp != null) {
                  json = jsonDecode(resp.body);
                  if (json != null) {
                    var unidades = json['accordion'];

                    for (var unidade in unidades) {
                      acao = unidade['titulo']['acao'];
                      var nomeUnidade = unidade['titulo']['html'];
                      var codUnidade = regExp2.firstMatch(acao)?.group(1);
                      if (codUnidade != null) {
                        resp = await fetchData(listaCursosUrl + codUnidade);
                        if (resp != null) {
                          json = jsonDecode(resp.body);
                          if (json != null) {
                            var cursosMap = json['dados'];
                            if (cursosMap is List) {
                              for (var curMap in cursosMap) {
                                var curso = Curso(
                                  siglaUf: siglaUf,
                                  nomeUf: nomeUf,
                                  nomeMunicipio: nomeMunicipio,
                                  codMunicipio: codMunicipio,
                                  nomeUnidade: nomeUnidade,
                                  codUnidade: codUnidade,
                                  modalidadeEnsino:
                                      curMap['Modalidade de Ensino'],
                                  nomeCurso: curMap['Curso'],
                                  tipoOferta: curMap['Tipo de Oferta'],
                                );

                                await file.writeAsString(
                                  convert.jsonEncode(curso.toMap()) + ',',
                                  flush: true,
                                  mode: FileMode.append,
                                );
                                print('curso: $count');
                                count++;
                              }
                            }
                          } else {
                            print('error count: $count json: $json');
                          }
                        } else {
                          print('error count: $count resp: $resp');
                        }
                      }
                    }
                  } else {
                    print('error count: $count json: $json');
                  }
                } else {
                  print('error count: $count url: ${url}');
                }
              }
            }
          } else {
            print('error count: $count json: $json');
          }
        } else {
          print('error count: $count url: $url');
        }
      }
    }
  } catch (e, s) {
    print('error $e $s');
  }

  await file.writeAsString(']', mode: FileMode.append);
}

class Curso {
  String siglaUf;
  String nomeUf;
  String nomeMunicipio;
  String codMunicipio;
  String nomeUnidade;
  String codUnidade;
  String modalidadeEnsino;
  String nomeCurso;
  String tipoOferta;

  Curso({
    required this.siglaUf,
    required this.nomeUf,
    required this.nomeMunicipio,
    required this.codMunicipio,
    required this.nomeUnidade,
    required this.codUnidade,
    required this.modalidadeEnsino,
    required this.nomeCurso,
    required this.tipoOferta,
  });

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'siglaUf': siglaUf,
      'nomeUf': nomeUf,
      'nomeMunicipio': nomeMunicipio,
      'codMunicipio': codMunicipio,
      'nomeUnidade': nomeUnidade,
      'codUnidade': codUnidade,
      'modalidadeEnsino': modalidadeEnsino,
      'nomeCurso': nomeCurso,
      'tipoOferta': tipoOferta,
    };
  }

  factory Curso.fromMap(Map<String, dynamic> map) {
    return Curso(
      siglaUf: map['siglaUf'] as String,
      nomeUf: map['nomeUf'] as String,
      nomeMunicipio: map['nomeMunicipio'] as String,
      codMunicipio: map['codMunicipio'] as String,
      nomeUnidade: map['nomeUnidade'] as String,
      codUnidade: map['codUnidade'] as String,
      modalidadeEnsino: map['modalidadeEnsino'] as String,
      nomeCurso: map['nomeCurso'] as String,
      tipoOferta: map['tipoOferta'] as String,
    );
  }
}

dados

cursos_tecnicos_mec_sistec.json

@insinfo
Copy link
Author

insinfo commented Aug 3, 2024

também iniciei um script em dart para baixar os dados do e-Mec

import 'package:puppeteer/puppeteer.dart';

const url = 'https://emec.mec.gov.br/emec/nova';
const siglasEstados = [
  'AC', // Acre
  'AL', // Alagoas
  'AP', // Amapá
  'AM', // Amazonas
  'BA', // Bahia
  'CE', // Ceará
  'DF', // Distrito Federal
  'ES', // Espírito Santo
  'GO', // Goiás
  'MA', // Maranhão
  'MT', // Mato Grosso
  'MS', // Mato Grosso do Sul
  'MG', // Minas Gerais
  'PA', // Pará
  'PB', // Paraíba
  'PR', // Paraná
  'PE', // Pernambuco
  'PI', // Piauí
  'RJ', // Rio de Janeiro
  'RN', // Rio Grande do Norte
  'RS', // Rio Grande do Sul
  'RO', // Rondônia
  'RR', // Roraima
  'SC', // Santa Catarina
  'SP', // São Paulo
  'SE', // Sergipe
  'TO', // Tocantins
];
void main() async {
  final browser = await puppeteer.launch(
      devTools: false,
      headless: false,
      defaultViewport: DeviceViewport(width: 1920, height: 1003), //, //null
      args: [
        // '--start-maximized' // you can also use '--start-fullscreen'
        '--window-size=1920,1080'
      ]);

  var page = await browser.newPage();

  await page.goto(url, wait: Until.domContentLoaded);
  await Future.delayed(Duration(milliseconds: 400));

  final idSelectUf = '#sel_sg_uf';
  final idBtnPesqAvancada = '#btnPesqAvancada';
  final idTableDataGrid = '#tbDataGridNova';

  await page.waitForSelector(idSelectUf);
  await page.select(idSelectUf, ['AC']);
  print('select estado');
  await Future.delayed(Duration(milliseconds: 1000));
  await page.click(idBtnPesqAvancada);
  print('click idBtnPesqAvancada');
  await Future.delayed(Duration(milliseconds: 1000));
  await page.waitForSelector(idTableDataGrid);
  await Future.delayed(Duration(milliseconds: 400));

  final idItemsPerPage = '#paginationItemCountItemdiv_listar_consulta_avancada';

  if (await isExist(page, idItemsPerPage)) {
    await page.select(
        idItemsPerPage, ['/emec/nova-index/listar-consulta-avancada/list/300']);
    await page.waitForSelector(idTableDataGrid);
    await Future.delayed(Duration(milliseconds: 1000));
  }

  final dados = await getTableAsJson(page, idTableDataGrid);
  print('dados: $dados');

  //await browser.close();
}

/// paginação
String extrairTotalRegistros(String input) {
  final regex = RegExp(r'de (\d+)\s*\|');
  final match = regex.firstMatch(input);

  if (match != null) {
    return match.group(1)!;
  } else {
    throw Exception("Nenhum número encontrado");
  }
}

Future<bool> isExist(Page page, String selector) async {
  try {
    await page.waitForSelector(selector, timeout: Duration(milliseconds: 200));
    return true;
  } catch (error) {
    return false;
  }
}

Future<String> getTableAsJson(Page page, String selector) async {
  var res = await page.evaluate('''() => {
  var table = document.querySelector("$selector");
  var data = [];
    var headers = [];
    
    // Get the headers
    var headerCells = table.querySelectorAll("thead th");
    for (var i = 0; i < headerCells.length; i++) {
        headers.push(headerCells[i].innerText.trim());
    }
    
    // Get the rows
    var rows = table.querySelectorAll("tbody tr");
    for (var i = 0; i < rows.length; i++) {
        var row = {};
        var cells = rows[i].querySelectorAll("td");
        for (var j = 0; j < cells.length; j++) {
            row[headers[j]] = cells[j].innerText.trim();
        }
        data.push(row);
    }
    var jsonData = data;
    console.log(jsonData);
    return JSON.stringify(jsonData);
}''');
  return res;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants