1

Como montar um screener da B3 com dados do Fundamentus (duas URLs e uma tabela HTML)

Quem faz análise fundamentalista na B3 vive dentro de screener de terceiros. E na
hora de levar o dado cru para a sua planilha, o seu backtest ou o seu modelo,
esbarra sempre no mesmo trio: export limitado, filtro atrás de assinatura, ou
copiar-colar célula por célula. O dado em si — indicador fundamentalista de empresa
listada — é público na origem. O que falta é um jeito programático de pegá-lo.

Existe um, e é mais simples do que parece. O Fundamentus, um dos sites mais antigos
de análise fundamentalista do Brasil, publica o mercado inteiro em duas páginas HTML
— uma tabela cada, sem login, sem paginação e sem anti-bot:

https://www.fundamentus.com.br/resultado.php        ← todas as ações
https://www.fundamentus.com.br/fii_resultado.php    ← todos os FIIs

Um GET em cada e você tem, na contagem de hoje, 987 ações e 552 FIIs com os
principais indicadores por linha. Este artigo mostra como transformar essas duas
tabelas num screener de verdade — incluindo as três pegadinhas de parsing que fazem
a maioria dos scripts falhar na primeira tentativa — e o que dá (e o que não dá)
para fazer com esse dado.

O que vem em cada tabela

Ações (resultado.php) — por papel: cotação, P/L, P/VP, PSR, dividend
yield
, P/Ativo, P/Capital de Giro, P/EBIT, P/Ativo Circulante Líquido, EV/EBIT,
EV/EBITDA
, margens (bruta, EBIT, líquida), liquidez corrente, ROIC, ROE,
liquidez em bolsa (2 meses), patrimônio líquido, dívida bruta/patrimônio e
crescimento de receita em 5 anos.

FIIs (fii_resultado.php) — por fundo: segmento, cotação, FFO yield, dividend
yield, P/VP
, valor de mercado, liquidez, quantidade de imóveis, preço do m²,
aluguel por m², cap rate e vacância média
. Esse bloco imobiliário (cap rate,
vacância, m²) é o tipo de coluna que raramente aparece de graça numa tabela única em
outro lugar.

As três pegadinhas de parsing

Se você fizer um fetch ingênuo, vai tropeçar em três coisas — todas contornáveis
em uma linha cada:

1. O encoding é ISO-8859-1, não UTF-8. O Fundamentus é um site antigo e serve
Latin-1. Se você decodificar como UTF-8, todo acento vira lixo (Consticssãoo).
Em shell, resolve com iconv; em Node, decodifique o buffer com latin1:

curl -s -H "User-Agent: Mozilla/5.0" \
  "https://www.fundamentus.com.br/resultado.php" \
  | iconv -f ISO-8859-1 -t UTF-8 > acoes.html

2. Os números vêm em formato pt-BR. 1.234.567,89 usa ponto de milhar e vírgula
decimal; percentuais vêm como 12,34%; valor ausente é -. A normalização é:
remover % e espaços, remover os pontos, trocar vírgula por ponto, e tratar -
como nulo. Sem isso, Number("2,90") vira NaN e seu filtro de P/L silenciosamente
descarta o mercado inteiro.

3. Mande um User-Agent de navegador. Requisição sem UA (ou com UA de script) tem
chance de voltar bloqueada. Um UA de Chrome comum resolve — está no exemplo acima.

Um quarto detalhe que economiza dor de cabeça: não mapeie as colunas pelo texto do
cabeçalho
(que tem acento e sofre com o encoding); mapeie por posição. E para
separar linha de dado de linha de cabeçalho/rodapé, o padrão do ticker é um filtro
excelente: a primeira célula de toda linha válida casa com ^[A-Z]{4}\d{1,2}$
(PETR4, MXRF11, TAEE11). Tudo que não casa, descarta.

O que dá pra filtrar (exemplos, não recomendações)

Com o mercado inteiro numa estrutura de dados, screening vira uma expressão booleana.
Três exemplos clássicos, citados aqui como fórmulas conhecidas da literatura — não
como recomendação de investimento:

  • Corte de liquidez primeiro. liquidez_2meses > 200000 elimina papel que não
    negocia — sem esse corte, todo screener devolve uma lista de micos ilíquidos com
    indicadores lindos e spread impraticável.
  • Estilo Graham: p_l > 0 AND p_vp > 0 AND p_l * p_vp <= 22.5 (o clássico
    "número de Graham" combinando preço/lucro e preço/patrimônio).
  • Renda com FIIs, estilo Bazin: dividend_yield >= 6 AND p_vp <= 1.05 AND vacancia_media < 10 AND liquidez > 100000 — yield com teto de preço sobre
    patrimônio e vacância controlada.

Rodando isso numa planilha, num script ou num notebook, você tem em segundos o que
levaria uma tarde de cliques — e com a régua sua, documentada, reproduzível.

O que esse dado NÃO é (leia antes de usar)

  • Não é tempo real. A cotação do Fundamentus vem com atraso — serve para
    screening e estudo, não para decisão intradiária.
  • Fundamento reflete o último balanço. P/L, ROE, margens etc. são calculados
    sobre os últimos demonstrativos publicados pela empresa — entre um trimestre e
    outro, o indicador não se move com a notícia de ontem.
  • É um site de terceiro, não uma API oficial da B3. A tabela é HTML e pode mudar
    de layout sem aviso. O contrato não é garantido — é estável há anos, mas trate
    como scraping, com validação no parse.
  • Indicador calculado tem metodologia. O número que aparece é o cálculo do
    Fundamentus. Para decisão séria, confira o dado na fonte primária (release/CVM).
  • Nada aqui é recomendação de investimento. É encanamento de dados.

Se você não quiser escrever o parser

Empacotei exatamente esse fluxo — fetch com UA correto, decode Latin-1, parse por
posição com o regex de ticker, normalização pt-BR → número JS — num Apify Actor:
brazil-b3-screener. Você
escolhe stocks, fiis ou both (e opcionalmente uma lista de tickers), e ele
devolve o mercado como JSON/CSV/Excel, com API e MCP para chamar de um agente de IA,
e agendamento para rodar todo dia antes do pregão. Custa $0.002 por ativo
retornado
e run que não retorna nada custa zero.

Mas as duas URLs são públicas e o parsing está descrito acima inteiro — se você só
precisava saber que elas existem, boa planilha. Esse era o ponto do artigo.

Carregando publicação patrocinada...