
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
cei-crawler
Advanced tools
Crawler para ler dados do Canal Eletrônico do Investidor
Para versão antiga do CEI que não possui captcha obrigatório (por enquanto), utilize o cei-crawler v2
Essa versão do crawler varre a Nova Area Logada do CEI. Essa área logada possui um captcha para que seja feito o login e por isso existem algumas estratégias de implementação para fazer o bypass do mesmo. Além disso, o CEI agora possui uma API. Tudo que o crawler faz basicamente é encapsular as chamadas dessas API's. Portanto, o formato dos dados vem direto do CEI, não há transformação feita por esse crawler. Sendo assim, caso haja algo estranho ou errado nos dados retornados, provavelmente é o próprio CEI que está retornando.
O cei-crawler utiliza as seguintes dependências:
Caso o cei-crawler tenha te ajudado e você queira fazer alguma doação pra me ajudar a mantê-lo, utilize o QR code abaixo :)
Mande também seu nome e usuário do GitHub (caso tenha) que eu coloco aqui no README. Obrigado!
PIX: joao.menighin@gmail.com
Criei o cei-crawler para um projeto de acompanhamento de investimentos. Caso esteja procurando algo nesse sentido, confira o Stoincs!
Basta instalar utilizando o NPM:
npm install --save cei-crawler
Crie uma instância do CeiCrawler passando os parametros necessários e invoque o método desejado:
let ceiCrawler = new CeiCrawler('username', 'password', {/* options */});
ceiCrawler.login(); // Login é opcional, pois antes de cada método o cei-crawler irá verificar se já esta logado.
// A vantagem em realizar o login em um passo diferente é para o tratamento de erros
A nova área logada do CEI possui validação por captcha. Não há forma simples de resolver e por isso algumas estratégias de resolução são implementadas.
Essas estratégias são setadas na instanciação do crawler, com o objeto de options. As disponíveis são:
raw-tokenNessa estratégia de login, não é necessário informar usuário e senha porém deve-se informar o token e o cache-guid do usuário logado.
Essa estratégia é útil caso você possua algum serviço terceiro que faça o login no CEI e pegue o token pra você.
Exemplo:
const ceiCrawler = new CeiCrawler(_, _, {
loginOptions: {
strategy: 'raw-token'
},
auth: {
"cache-guid": "cache-guid do usuário logado",
token: "JWT do usuário logado"
}
});
const values = await ceiCrawler.getConsolidatedValues();
user-resolveNessa estratégia de login, o usuário será promptado para fazer o login ele mesmo em uma janela de browser que será aberta. O crawler tenta preencher usuário e senha para você de forma que o input manual é somente para resolução do Captcha. Uma vez feito o login, o crawler trata de pegar as credencias e seguir adiante chamando os métodos. Nas opções do login deve-se também ser informado um caminho do browser para que o puppeteer o controle.
Exemplo:
const ceiCrawler = new CeiCrawler('user', 'password', {
loginOptions: {
strategy: 'user-resolve',
browserPath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
}
});
const values = await ceiCrawler.getConsolidatedValues();
getConsolidatedValues()Retorna os investimentos consolidados num valor total e divididos em subcategorias
let consolidated = await ceiCrawler.getConsolidatedValues();
Resultado:
{
"total": 10000,
"subTotais": [
{
"categoriaProduto": "Renda Variável",
"totalPosicao": 5000,
"percentual": 0.5
},
{
"categoriaProduto": "Tesouro Direto",
"totalPosicao": 5000,
"percentual": 0.5
}
]
}
getPosition(date, page)Retorna as posições da tela "Posição" em todas as categorias de investimentos.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| date | Dte | null | Data da posição. Caso seja passado null ou nenhum valor, será usada a ultima data de processamento do CEI. |
| page | Number | 1 | Paginação dos dados. Por default retorna a primeira página. |
let position = await ceiCrawler.getPosition();
Resultado:
{
"paginaAtual": 1,
"totalPaginas": 1,
"itens": [
{
"categoriaProduto": "RendaVariavel",
"tipoProduto": "Acao",
"descricaoTipoProduto": "Ações",
"posicoes": [
{
"id": "gfw2455-8a79-4127-990b-587sa37",
"temBloqueio": false,
"instituicao": "INTER DISTRIBUIDORA DE TITULOS E VALORES MOBILIARIOS LTDA",
"quantidade": 100,
"valorAtualizado": 2377.00,
"precoFechamento": 23.77,
"produto": "BIDI4 - BANCO INTER S.A.",
"tipo": "PN",
"marcacoes": [],
"codigoNegociacao": "BIDI4",
"documentoInstituicao": "358743882",
"existeLogotipo": false,
"disponivel": 100,
"documento": "48377283492",
"razaoSocial": "BANCO INTER S.A.",
"codigoIsin": "BRBRHEU2",
"distribuicao": "114",
"escriturador": "BANCO BRADESCO S/A",
"valorBruto": 0
}
],
"totalPosicao": 2377.00,
"totalItemsPagina": 1
},
{
"categoriaProduto": "TesouroDireto",
"tipoProduto": "TesouroDireto",
"descricaoTipoProduto": "Tesouro Direto",
"posicoes": [
{
"id": "hfd4564-e70a-4596-93fd-987654dvbhw",
"temBloqueio": false,
"instituicao": "XP INVESTIMENTOS CCTVM S/A",
"quantidade": 1.01,
"valorAtualizado": 2200,
"vencimento": "2024-08-15T00:00:00",
"valorAplicado": 2000,
"produto": "Tesouro IPCA+ 2024",
"marcacoes": [],
"documentoInstituicao": "8573938583",
"existeLogotipo": false,
"indexador": "IPCA",
"disponivel": 1.01,
"documento": "7658493485",
"codigoIsin": "VRSIYASU@",
"valorBruto": 2038,
"nomeTituloPublico": "Tesouro IPCA+ 2024",
"valorLiquido": 29882,
"percRentabilidadeContratada": 4.71
}
],
"totalPosicao": 22000,
"totalItemsPagina": 5
}
],
"detalheStatusCode": 0,
"excecoes": []
}
getPositionDetail(id, category, type)Retorna o detalhe de uma posição da lista anterior.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| id | String | undefined | UUID da posição. Foi observado que o UUID de uma mesma posição pode mudar ao longo do tempo e essa requisição falhar após pegar a lista com o getPosition() |
| category | String | undefined | Categoria da posição informada no método getPosition(). |
| type | String | undefined | Tipo da posição informada no método getPosition(). |
let positionDetail = await ceiCrawler.getPositionDetail('gfw2455-8a79-4127-990b-587sa37', 'RendaVariavel', 'Acao');
Resultado:
{
"codigoIsin": "BRBIDIACNPR0",
"distribuicao": "114",
"empresa": "BANCO INTER S.A.",
"escriturador": "BANCO BRADESCO S/A",
"codigoNegociacao": "BIDI4",
"disponivel": 100,
"indisponivel": 0,
"quantidade": 100,
"marcacoes": [],
"possuiMarcacoes": false,
"existeLogotipo": false,
"documentoInstituicao": "358743882"
}
getAccountStatement(startDate, endDate, page)Retorna as movimentações da aba "Movimentação" no CEI.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| startDate | Date | null | Data de inicio para trazer as movimentações. Caso null, será utilizada a ultima data de processamento do CEI menos 1 mês. |
| endDate | Date | null | Data fim para trazer as movimentações. Caso null, será utilizada a ultima data de processamento do CEI. |
| page | Number | 1 | Paginação dos dados. Por default retorna a primeira página. |
let accountStatement = await ceiCrawler.getAccountStatement();
Resultado:
{
"paginaAtual": 1,
"totalPaginas": 2,
"itens": [
{
"data": "2021-08-02T00:00:00",
"movimentacoes": [
{
"tipoOperacao": "Credito",
"tipoMovimentacao": "Juros Sobre Capital Próprio",
"nomeProduto": "BIDI4 - BANCO INTER S.A.",
"instituicao": "INTER DISTRIBUIDORA DE TITULOS E VALORES MOBILIARIOS LTDA",
"quantidade": 100,
"valorOperacao": 1.49,
"precoUnitario": 0.01
}
],
"totalItemsPagina": 1
},
{
"data": "2021-07-30T00:00:00",
"movimentacoes": [
{
"tipoOperacao": "Debito",
"tipoMovimentacao": "Transferência",
"nomeProduto": "ALZR11 - ALIANZA TRUST RENDA IMOBILIARIA FDO INV IMOB",
"instituicao": "RICO INVESTIMENTOS - GRUPO XP",
"quantidade": 5
},
{
"tipoOperacao": "Credito",
"tipoMovimentacao": "Transferência",
"nomeProduto": "ALZR11 - ALIANZA TRUST RENDA IMOBILIARIA FDO INV IMOB",
"instituicao": "XP INVESTIMENTOS CCTVM S/A",
"quantidade": 5
}
],
"totalItemsPagina": 2
}
],
"detalheStatusCode": 0,
"excecoes": []
}
getIpos(date, page)Retorna os IPOs da tela "Ofertas Públicas" no CEI.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| date | Date | null | Data de consulta. Caso seja passado null ou nenhum valor, será usada a ultima data de processamento do CEI. |
| page | Number | 1 | Paginação dos dados. Por default retorna a primeira página. |
let ipos = await ceiCrawler.getIPOs();
Resultado:
{
"paginaAtual": 1,
"totalPaginas": 1,
"itens": [
{
"data": "2021-07-27T00:00:00",
"ofertasPublicas": [
{
"id": "c80c8b8f-62d2-4b48-b242-b0f310cfa95a",
"dataLiquidacao": "2021-07-27T00:00:00",
"nomeEmpresa": "INVESTO ETF MSCI US TECHNOLOGY FDO INV IND INV EXT",
"tipoOferta": "OUTRO",
"oferta": "ETF INVESTO",
"nomeInstituicao": "INTER DISTRIBUIDORA DE TITULOS E VALORES MOBILIARIOS LTDA",
"quantidade": 10,
"preco": 10,
"valor": 100
}
],
"totalItemsPagina": 1
}
],
"detalheStatusCode": 0,
"excecoes": []
}
getIPODetail(id)Retorna o detalhe de uma posição da lista anterior.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| id | String | undefined | UUID do IPO. Foi observado que o UUID de um mesmo IPO pode mudar ao longo do tempo e essa requisição falhar após pegar a lista com o getIPOs() |
let ipoDetail = await ceiCrawler.getIPODetail('c80c8b8f-62d2-4b48-b242-b0f310cfa95a');
Resultado:
{
"nomeProduto": "OUTRO INVESTO ETF MSCI US TECHNOLOGY FDO INV IND INV EXT",
"nomeInstituicao": "INTER DISTRIBUIDORA DE TITULOS E VALORES MOBILIARIOS LTDA",
"ativo": {
"nomeEmpresa": "INVESTO ETF MSCI US TECHNOLOGY FDO INV IND INV EXT",
"ticker": "USTK11L",
"oferta": "ETF INVESTO",
"codigoIsin": "BRUSTKCTF007"
},
"valores": {
"preco": 10,
"precoMaximo": 0,
"valor": 100
},
"reserva": {
"modalidade": "Compra/Integralização de cotas do ETF INVESTO",
"quantidade": 10,
"valor": 0
},
"quantidadeAlocada": 10,
"dataLiquidacao": "2021-07-27T00:00:00"
}
getStockTransactions(startDate, endDate, page)Retorna os dados da aba "Negociação" no CEI.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| startDate | Date | null | Data de inicio para trazer as negociações. Caso null, será utilizada a ultima data de processamento do CEI menos 1 mês. |
| endDate | Date | null | Data fim para trazer as negociações. Caso null, será utilizada a ultima data de processamento do CEI. |
| page | Number | 1 | Paginação dos dados. Por default retorna a primeira página. |
let stockTransactions = await ceiCrawler.getStockTransactions();
Resultado:
{
"paginaAtual": 1,
"totalPaginas": 1,
"itens": [
{
"data": "2021-07-20T00:00:00",
"totalCompra": 1000,
"totalVenda": 0,
"negociacaoAtivos": [
{
"tipoMovimentacao": "Compra",
"mercado": "Mercado à Vista",
"nomeInstituicao": "RICO INVESTIMENTOS - GRUPO XP",
"codigoNegociacao": "PNVL3",
"quantidade": 100,
"preco": 10.00,
"valor": 1000.00
}
],
"totalItemsPagina": 1
}
],
"detalheStatusCode": 0,
"excecoes": []
}
getProvisionedEvents(date, page)Retorna os eventos da tela "Eventos Provisionados" no CEI.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| date | Date | null | Data de consulta. Caso seja passado null ou nenhum valor, será usada a ultima data de processamento do CEI. |
| page | Number | 1 | Paginação dos dados. Por default retorna a primeira página. |
let events = await ceiCrawler.getProvisionedEvents();
Resultado:
{
"totalValorLiquido": 8.62,
"paginaAtual": 1,
"totalPaginas": 1,
"itens": [
{
"id": "9cc87804-f9ae-143a-acfb-c953f38c72dd",
"produto": "WEGE3 - WEG S/A",
"tipo": "ON",
"tipoEvento": "JUROS SOBRE CAPITAL PRÓPRIO",
"previsaoPagamento": "2021-08-11T00:00:00",
"instituicao": "INTER DISTRIBUIDORA DE TITULOS E VALORES MOBILIARIOS LTDA",
"quantidade": 300,
"precoUnitario": 0.03,
"valorLiquido": 8.62,
"totalItemsPagina": 1
}
],
"detalheStatusCode": 0,
"excecoes": []
}
getProvisionedEventDetail(id)Retorna o detalhe de um evento provisionado da lista anterior.
| Parâmetro | Tipo | Default | Descrição |
|---|---|---|---|
| id | String | undefined | UUID do evento. Foi observado que o UUID de um mesmo evento pode mudar ao longo do tempo e essa requisição falhar após pegar a lista com o getProvisionedEvents() |
let eventDetail = await ceiCrawler.getProvisionedEventDetail('9cc87804-f9ae-143a-acfb-c953f38c72dd');
Resultado:
{
"codigoNegociacao": "WEGE3",
"codigoIsin": "BRWEGEACNOR0",
"distribuicao": "202",
"escriturador": "BANCO BRADESCO S/A",
"empresa": "WEG S/A",
"dataAprovacao": "2021-03-23T00:00:00",
"dataAtualizacao": "2021-03-30T00:00:00",
"dataEx": "2021-03-29T00:00:00",
"impostoRenda": 15,
"valorImpostoRenda": 1.52,
"valorBruto": 10.14,
"disponivel": 100,
"indisponivel": 0,
"produto": "WEGE3 - WEG S/A",
"tipo": "ON",
"tipoEvento": "JUROS SOBRE CAPITAL PRÓPRIO",
"previsaoPagamento": "2021-08-11T00:00:00",
"quantidade": 100,
"precoUnitario": 0.03,
"valorLiquido": 8.62
}
Na criação de um CeiCrawler é possivel especificar alguns valores para o parâmetro options que modificam a forma que o crawler funciona. As opções são:
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
| debug | Boolean | false | Se true, printa mensages de debug no log. |
| loginOptions.strategy | String | user-resolve | Estratégia utilizada no login. Veja Login & Captcha para mais informações. |
| loginOptions.browserPath | String | undefined | Caminho para o executavél do browser que será controlado para resolucao do Captcha. Veja Login & Captcha para mais informações. |
| auth.token | String | undefined | Token JWT do usuário logado no CEI. Utilizado quando a estratégia de login é raw-token |
| auth.cache-guid | String | undefined | UUID da sessão do usuário logado no CEI. Utilizado quando a estratégia de login é raw-token |
Exemplo:
const ceiCrawlerOptions = {
debug: true,
loginOptions: {
strategy: 'user-resolve',
browserPath: 'path/to/browser.exe'
}
};
let ceiCrawler = new CeiCrawler('username', 'password', ceiCrawlerOptions);
O CEI Crawler possui um exceção própria, CeiCrawlerError, que é lançada em alguns cenários. Essa exceção possui um atributo type para te direcionar no tratamento:
| type | Descrição |
|---|---|
| UNAUTHORIZED | Lançada quando uma request retorna 401. Isso pode significar que o token utiliza é inválido ou expirou. |
| BAD_REQUEST | Lançada quando uma requisição falha por má formação. Pode ser um parâmetro errado, uma data menor que o limite minimo, etc. |
| TOO_MANY_REQUESTS | O CEI faz throttling de requisições. Se ao usar o crawler você fizer muitas requisições rapidamente esse erro pode ser retornado |
| INVALID_LOGIN_STRATEGY | Lançada quando informada uma estratégia de login inválida. |
Exemplo de como fazer um bom tratamento de erros:
const CeiCrawler = require('cei-crawler');
const { CeiErrorTypes } = require('cei-crawler')
const ceiCrawler = new CeiCrawler('usuario', 'senha', { navigationTimeout: 20000 });
try {
const positions = ceiCrawler.getPositions();
} catch (err) {
if (err.name === 'CeiCrawlerError') {
if (err.type === CeiErrorTypes.UNAUTHORIZED)
// Handle unauthrozied
else if (err.type === CeiErrorTypes.TOO_MANY_REQUESTS)
// Handle too many requests
// else ...
} else {
// Handle generic errors
}
}
MIT
FAQs
Crawler para pegar dados do Canal Eletronico do Investidor
We found that cei-crawler demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.