Python

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

36 comentários sobre “Python – Baixar NFS-e Portal Nacional

  • Fábio, você teria um vba que leia o arquivo xml para o excel? semelhante ao da NF-e

    Resposta
    • Fabio MitsuedaAutor do post

      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?

      Resposta
  • 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

    Resposta
    • Fabio MitsuedaAutor do post

      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.

      Resposta
  • 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.

    Resposta
  • Tem algum código já criado para baixar pelo certificado A1 em vez de CNPJ e senha?

    Resposta
    • Fabio MitsuedaAutor do post

      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.

      Resposta
  • 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!

    Resposta
  • 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!

    Resposta
    • Fabio MitsuedaAutor do post

      que bom que ajudou

      Resposta
  • 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?

    Resposta
      • Fabio MitsuedaAutor do post

        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.

        Resposta
    • Boa tarde!
      Também estou com essa mesma situação, alguém conseguiu executar?

      Resposta
      • Fabio MitsuedaAutor do post

        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.

        Resposta
        • 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.

          Resposta
        • Bom dia Fabio, belo trabalho, mas o arquivo executável continua fechando sozinho poderia disponibilizar o novo link? muito obrigado

          Resposta
    • Fabio MitsuedaAutor do post

      Subi o codigo que vc me enviou, obrigado pela contribuição.

      Resposta
  • Fabio, obrigada por compartilhar seu conhecimento e código conosco. Toda ajuda é sempre bem vida.

    Resposta
  • Fabio, parabéns pelo serviço!
    Teria como colocar a opção de buscar as notas fiscais de serviços tomados?

    Resposta
  • 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.

    Resposta
    • Fabio MitsuedaAutor do post

      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.

      Resposta
  • 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?

    Resposta
    • Como vc fez isso Bruno, consegue nos ajudar?

      Resposta
      • 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

        Resposta
  • boa tarde desde ja agradeço por compartilhar< teria como acessar com certificado digital

    Resposta
  • wonderlandinventive2f2bfc00e8

    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)

    Resposta
  • 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

    Resposta
  • 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?

    Resposta
  • 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?

    Resposta
  • Olá, como faço para o arquivo .exe baixar a nota de entrada também??

    Resposta
  • 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.

    Resposta
  • 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

    Resposta
  • 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

    Resposta

Deixe uma resposta