Python – Baixar NFS-e Portal Nacional
Nessa postagem quero compartilhar com vocês um código em Python utilizando o Playwright, para baixar os arquivos XML direto do site do emissor nacional, utilizando usuario e senha.
Não vou entrar no detalhe de como instalar o Python, ou a biblioteca do Playwright, para isso existe excelentes conteudos em portugues, que vou deixar o link abaixo. Realmente são videos muito didaticos e que irão agregar muito.
Sobre o Playwright um video muito bom é o do pessoal da Hashtag Programação com o Professor Lira, clique aqui para assistir o video no youtube.
Sobre o Python um video que agregou muito pra mim foi o da Bóson Treinamentos com o Professor Fábio dos Reis, clique aqui para assitir o video no youtube.
Deixei o codigo bastante comentado, é um código simples, que pode ser melhorado, conto com vocês para compatilhar as melhorias.
O codigo entra no portal nacional de nota fiscal de serviço, com CNPJ e Senha, lista as notas emitidas, faz a leitura, ao finalizar você terá todas as notas baixadas no C:\Projetos Phyton\NFSe-XML\.
Para que seja uma ferramenta funcional, criei um executavel, caso queira utilizar, mas não tem nenhum conhecimento de Python, e pode ser baixado clicando aqui e seguindo as etapas abaixo:
Ao clicar no link acima será aberta uma janela para baixar o arquivo executavel, baixe em um local na sua maquia e descompacte o arquivo.

Após baixar e descompactar o arquivo, na pasta descompactada terá um arquivo executave e uma pasta, precisa manter como esta abaixo, no arquivo executavel click com o direito para desbloquear (Segurança do Windows)

Na aba Geral, clique em Desbloquer, depois clique em Aplicar depois em OK.

Após desbloquear o arquivo de um duplo click no arquivo NFSe-Nacional.exe, será aberto um prompt de comando conforme abaixo, insira CNPJ (apenas numeros), Senha, e data inicial e data final no formato dd/mm/aaaa.

Após a execução do codigo, serão criadas pastas no diretorio C:\Projetos Phyton\NFSe-Xml conforme imagem abaixo, e dentro delas estará os arquivos Xml’s.

Abaixo codigo na integra, se preferir pode clicar aqui para baixar o modulo.
#Importando biblioteca para uso do codigo
from playwright.sync_api import sync_playwright, expect
from datetime import datetime, date
import calendar
#Função para gerar datas de incio e fim de mes
def intervalos_mensais_str(data_inicial: str, data_final: str):
# Converte strings dd/mm/yyyy para date
dt_ini = datetime.strptime(data_inicial, "%d/%m/%Y").date()
dt_fim = datetime.strptime(data_final, "%d/%m/%Y").date()
intervalos = []
ano = dt_ini.year
mes = dt_ini.month
while True:
primeiro_dia = date(ano, mes, 1)
ultimo_dia = date(ano, mes, calendar.monthrange(ano, mes)[1])
inicio_intervalo = max(primeiro_dia, dt_ini)
fim_intervalo = min(ultimo_dia, dt_fim)
# Converte datas para o formato dd/mm/yyyy
intervalo_str = (
inicio_intervalo.strftime("%d/%m/%Y"),
fim_intervalo.strftime("%d/%m/%Y")
)
intervalos.append(intervalo_str)
# Encerra quando chegar ao mês final
if ano == dt_fim.year and mes == dt_fim.month:
break
# Avança um mês
mes += 1
if mes > 12:
mes = 1
ano += 1
return intervalos
#Variavel que representa o site
strUrl = 'https://www.nfse.gov.br/EmissorNacional/Login'
#Variavel que representa o CNPJ
strCNPJ = input('Digite o CNPJ: ')
#Variavel que representa a senha
strSenha = input('Digite a senha: ')
#Variavel que representa a data inicial
strDtaIni = input('Digite a data inicial: ')
#Variavel que representa a data final
strDtaFim = input('Digite a data final: ')
#Variavel que representa o caminha a ser salvo os arquivos
strCaminho = 'C:/Projetos Phyton/NFSe-Xml/'
#Iniciando codigo de automação do navegador
with sync_playwright() as pw:
#Definindo o navegador Chrome
navegador = pw.chromium.launch(headless=False)
contexto = navegador.new_context()
#Definindo uma novaa pagina
pagina = contexto.new_page()
#Levando até o site da NFSe-Nacional
pagina.goto(strUrl)
#Inserindo o CNPJ
pagina.get_by_role("textbox", name="CPF/CNPJ").fill(strCNPJ)
#Inserindo a senha
pagina.get_by_role("textbox", name="Senha").fill(strSenha)
#Clicando em entrar
pagina.get_by_role("button", name="Entrar").click()
#Clicando em notas fiscais emitidas
pagina.get_by_role("link").filter(has_text="NFS-e Emitidas").click()
#Capturando intervalos
intervalos = intervalos_mensais_str(strDtaIni, strDtaFim)
for inicio, fim in intervalos:
#Inserindo as datas
pagina.locator("#datainicio").fill(inicio)
pagina.locator("#datafim").fill(fim)
pagina.get_by_role("button", name="Filtrar").click()
#Verificando se existem registro a serem baixados
if pagina.get_by_text('Total de ').count() > 0:
#Capturando a quantidade de registros da pagina
strReg = pagina.get_by_text('Total de ').inner_text().split(' ')[2]
x = int(strReg)
#Criando contador para laço de repetição
y = 0
#Iniciando laço de repetição
while True:
#Capturando quantidade de linhas da tabela
row_locator = pagina.locator("tbody tr")
row_count = row_locator.count() + 1
#Capturando o status da nota fiscal
strStatus = pagina.locator(".td-situacao > img").first.get_attribute('data-original-title')
#Iniciando download
pagina.get_by_role("link", name="").first.click()
with pagina.expect_download() as download_info:
pagina.get_by_role("link", name="Download XML").click()
download = download_info.value
download.save_as(strCaminho + strStatus + '/' + download.suggested_filename)
#Contando xml baixado
y = y + 1
#Baixando os demais itens
for i in range(2, row_count):
strStatus = pagina.locator("tr:nth-child(" + str(i) + ") > .td-situacao > img").get_attribute('data-original-title')
#Iniciando download
pagina.get_by_role("link", name="").nth(i-1).click()
with pagina.expect_download() as download_info:
pagina.get_by_role("link", name="Download XML").click()
download = download_info.value
download.save_as(strCaminho + strStatus + '/' + download.suggested_filename)
#Contando xml baixado
y = y + 1
#Caso ainda não tenha baixado todos os registros vá para proxima pagina
if y < x:
#Proxima pagina
pagina.get_by_role("link", name="").click()
pagina.wait_for_load_state("networkidle")
#Fechando o Navegador
#Do contrario saia do looping e feche o navegador
else:
break
navegador.close

Fábio, você teria um vba que leia o arquivo xml para o excel? semelhante ao da NF-e
Bom dia, eu até fiz um com numero da nota, data e valor. Se quiser posso te enviar. Acho que vou preparar uma postagem para isso, quais campos adicionais vc acha importante incluir?
Bom dia, Fábio! Desde já te agradeço. Suas postagens me ajudam bastante! Sobre os campos acredito que, além dos que citou, dados de IBS e CBS, tributos retidos e dados como local da prestação do serviço/incidência seriam bons também. Se puder enviar, te agradeço
Você tem um xml de exemplo? para não compartilhar os dados, vc pode abrir ele em formato txt e colocar 0 nos dados sensiveis e salvar, se tive me envia no mitsueda.fabio@gmail.com o que eu tenho aqui é simples nacional não tem essas tags.
Eu tenho, irei te enviar! Eu até fiz um aqui com essas tags com a ajuda do copilot, está quebrando um galho mas não sei se está tão bom, irei te enviar também.
Tem algum código já criado para baixar pelo certificado A1 em vez de CNPJ e senha?
Não tenho, esse codigo usa o Playwright como ferramenta de webscraping e a ferramenta até suporta indicar um arquivo pfx (que seria um A1), indicando o caminho e a senha desse arquivo, mas não da suporte para abrir o seletor de certificado do windows, ai teria que utilizar outra ferramenta ou pratica para esse resultado. Mas vou pesquisar pq estou tentando automatizar o acesso ao e-Cac usando botcity e acredito que vou conseguir algo, se eu tiver sucesso replico para essa solução. Mas ainda não tenho nada pronto.
Fabio, achei seu site pelo Contabeis.com.br e me ajudou demais. Muito obrigado! Agora, de fato, preciso apenas identificar o XML para Excel e conseguirei resolver um grande problema. Muito obrigado!
Boa tarde Fábio, queria te agradecer porque essa ferramenta salvou um tempo aqui viu! apareceu um MEI desenquadrado retroativo de 2 anos com ~2600 NFSe no portal rs… passarei a segui-lo lá no Youtube, Muito obrigado por compartilhar e ajudar os colegas da classe contábil.. se fossemos depender só do gov estamos lascados rs.. Muita paz, paciência e saúde para esse 2026, que Deus abençoe!
que bom que ajudou
Boa noite!
A ideia da automação é muito boa. Porém, ao tentar executar o processo pelo arquivo .exe, estou enfrentando um problema.
A execução inicia normalmente, abre o portal, começa o carregamento de baixar os xml, mas a janela fecha automaticamente logo em seguida.
Você saberia me informar o que pode estar causando esse erro e como posso corrigir?
estou com mesmo erro
Subi uma versão com uma correção, inclusão do trecho pagina.wait_for_load_state(“networkidle”) ao codigo, dica de um membro aqui do blog.
Boa tarde!
Também estou com essa mesma situação, alguém conseguiu executar?
Subi uma versão com uma correção, foi editada por um membro aqui do blog, incluiu a linha pagina.wait_for_load_state(“networkidle”) no codigo. Obrigado pela contribuição.
Fabio, onde se encontra o link com o arquivo exe atualizado? Não localizei no texto acima e ao realizar o download recebi a mesma versão.
Bom dia Fabio, belo trabalho, mas o arquivo executável continua fechando sozinho poderia disponibilizar o novo link? muito obrigado
Subi o codigo que vc me enviou, obrigado pela contribuição.
Fabio, obrigada por compartilhar seu conhecimento e código conosco. Toda ajuda é sempre bem vida.
Fabio, parabéns pelo serviço!
Teria como colocar a opção de buscar as notas fiscais de serviços tomados?
Fabio, poderia fazer a ferramenta sem login e senha, e sim ele executar no site já aberto? pois os acesso são por meio de certificado digital.
Hum na verdade a biblioteca que utilizei não aceita (ou pelo menos eu não sei como) utilizar a janela aberta, porque ele usa um browser teste, ate onde pesquisei para usar um certificado digital A1, precisaria modificar o projeto e passar o caminho do certificado e a senha, para que ele possa acessar. Mas ainda não consegui tempo pra dedicar nessa alteração.
Fabio bom dia, queria agradecer por compartilhar o codigo. Simples e muito funcional.
fiz a tradução para java e adicionei a possibilidade de login por certificado. Voce tem um github para adicionar como um fork?
Como vc fez isso Bruno, consegue nos ajudar?
Portei o codigo para o java e alterei para esperar eu entrar com certificado no chromium, alem de uma gui simples. Todo trabalho bruto ja ta feito, é so aprimorar
boa tarde desde ja agradeço por compartilhar< teria como acessar com certificado digital
Boa noite, Fabio. Estou precisando para as Nfs Recebidas tentei usar esse codigo acima, trocando apenas “NFS-e Emitidas” por “NFS-e Recebidas”, deu certo, porém ele vai para segunda pagina e para de baixar os xmls, sabe como resolvo? (ah Não tenho acesso com CNPJ, ai coloco qualquer coisa no login, deixo ele abrir o site assim que der o erro eu entro com certificado)
Bom dia, colegas!
Gostaria de compartilhar o lançamento da NFSe Plus, uma ferramenta desenvolvida para facilitar a rotina contábil e fiscal das empresas.
A plataforma permite:
Download em lote de NFS-e
Alertas automáticos de notas fiscais canceladas;
Painel simples e intuitivo para gestão das notas.
O serviço possui assinatura de R$ 9,90 por CNPJ, com 7 dias gratuitos para testes.
Acesse o site para conhecer: https://nfseplus.com.br
Olá Fabio! Estou recebendo a seguinte mensagem:
“ESTE APLICATIVO NAO PODE SER EXECUTADO EM SEU PC. PARA LOCALIZAR UMA VERSAO PARA SEU PC, CONTATE O FORNECEDOR DO SOFTWARE”
Saberias qual a solução?
Ola, a versão de download do executável, esta fechando sozinha, conseguiria corrigir? ele faz o download dos serviços tomados tbm? baixa os pdfs e xmls?
Olá, como faço para o arquivo .exe baixar a nota de entrada também??
Eu também queria esta opção.
Right, placed a few bets on vaidebbet, so let’s see! Site’s alright, easy enough to understand. Here’s hoping I can take home some earnings tonight! Good luck to those betting on vaidebbet.
Alright, gotta say, UP777 game download? Not bad, not bad at all! Easy to grab the games and pretty smooth sailing. Definitely worth a look if you’re hunting for some fresh titles. Check it out here: up777gamedownload
Linknew88, eh? Gave it a whirl, seemed legit and the process was straightforward. Found what I was looking for without too much hassle. Give it a shot, might just be your new go-to. What do you think? linknew88
Excelente, poderia fazer uma versão que entre com certificado digital do cliente? obg