Existe uma API para listar as mensagens de uma licitação?

Eu precisava automatizar um processo e para isso precisava do histórico de mensagens, existe alguma API com endpoint para isso?

Pelo comprasnet, existe captcha então não é possivel usar ferramentas de [
automação.

Seria listar paginado as memsmas mensagens de quando voce clicka no icone de carta, e abre a lista de mensagem

Link exemplo:
https://cnetmobile.estaleiro.serpro.gov.br/comprasnet-web/public/compras/acompanhamento-compra?compra=99019205900062024

4 Likes

Não sei de api, mas já automatizei o cadastro de proposta usando undetected-chromedriver + selenium com python, então na maior parte das vezes ele não pede captcha.

2 Likes

Bom dia,

Uma pena que já tenha passado 10 dias da data da sua publicação. Faz quase 1 ano que não programo em Python, mas consegui realizar a extração das mensagens do link que você forneceu sem problemas com captcha. Utilizei o undetected-chromedriver, que é uma versão modificada do Selenium. Também usei o navegador Brave, pois o Google Chrome no meu Linux está bugado.

Se o código estiver muito verboso, peço desculpas por isso, pois escrevi e reescrevi enquanto fazia testes. O arquivo está no formato “ipynb” porque acho ótimo para depuração. Apesar de ser formado em Análise de Sistemas, não sou desenvolvedor; sou analista de licitação e utilizei Python muitas vezes para automatizar tarefas próprias.

Hoje em dia, além dos pregões, tenho focado na criação de prompts para análises de editais e na automatização de impugnações, recursos e contrarrazões sem a necessidade de contratar advogados.

Confesso que me diverti um pouco fazendo o código. Pedi ajuda ao ChatGPT, pois, como disse, faz quase 1 ano que não programo nada.

Apesar de ter utilizado o WebDriverWait para aguardar o elemento ficar disponível para captura, precisei adicionar time.sleep, pois, ao fazer a paginação, o PNCP demora alguns segundos para atualizar as informações. Ou seja, mesmo que eu vá para a página 2, ele ainda continua mostrando informações da página 1. Então, coloquei 10 segundos de espera para garantir a atualização das novas mensagens. No início, encontrei um pouco de dificuldade, pois, apesar de a maioria das mensagens serem padronizadas, algumas não seguem o mesmo padrão.

Espero que isso te ajude futuramente. Pedi ao ChatGPT para gerar um README explicando todas as bibliotecas utilizadas e o código.

Abraços.

5 Likes

Pela documentação da API do comprasnet não verifiquei a possibilidade de ter acesso a este recurso.
A alternativa é adotar scrapping da página, mas é um recurso que pode vir a falhar quando houver alguma restrição de busca automática, como captcha.

@leonardo_raposo

Então leonardo eu consigo assim tambem da minha MAQUINA, mas eu teria que fazer isso numa escala massiva e subir na cloud, ae teria que usar proxy tb pq com certeza o captcha ia bloquear meu IP e isso adicionaria um custo a mais, eu queria uma solucão mais simples.

Testei sua solucao (usando o chrome), e não funcionou no modo headless… Com o Brave tu conseguiu rodar com Headless=True?

Rapaz, eu não sou a pessoa mais indicada para ajudá-lo, pois não sou desenvolvedor. No entanto, posso compartilhar a pesquisa que fiz ontem à noite.

Eu consegui rodar no modo headless, pois pesquisando, encontrei o framework SeleniumBase, que funcionou perfeitamente no modo headless.

Você pode encontrar o código no GitHub: link para o repositório.

O SeleniumBase também possui o modo undetected (UC), que ajuda a evitar a detecção de automação em sites.

Ele oferece várias funcionalidades. Aqui está a documentação: Documentação do SeleniumBase.

O código não está perfeito; deve haver parâmetros em excesso, pois eu peguei a documentação, testei a navegação de página e depois pedi para o ChatGPT refatorar usando o SeleniumBase.

Já testei várias vezes e ele rodou perfeitamente no modo headless no Chrome. Porém, aqui na empresa, estou usando Windows e não Linux.

Você me fez fazer algo que não fazia há séculos, que é olhar documentação.

Eu aconselho rodar o Selenium de forma convencional para capturar a mensagem de captcha e testar no código do SeleniumBase, assim você consegue identificar quando ele dá erro inválido de captcha e pode rodar o código novamente. O PNCP às vezes apresenta esse erro.

A documentação diz que o SeleniumBase espera automaticamente os elementos, mas para mim, aqui, não funcionou. Continuei a usar o WebDriverWait e time.sleep. Eu diminui o tempo de espera do time.sleep, pois as mensagens atualizaram rápido.

Se o SeleniumBase não funcionar, você talvez precise buscar opções de low-level ou alguém que já esteja acostumado a fazer scraping de várias maneiras, pois já vi gente no YouTube fazendo scraping da memória do computador ao abrir a página ou utilizando ADB com emulador Android.

1 Like

Rodei no Linux com headless=True e fui bloqueado pelo captcha (headless=False funcionou ok).

Vou arrumar um Windows para fazer o teste.

Agora não entendi seu ultimo ponto, o problema é ser detecatdo pelo captcha, o dado ta no servidor, as requests que retornam os dados que preciso, precisam de um parametro token que é gerado pelo hcaptcha, e se o hcaptcha detectar que sou um possivel robo esse token vai vir com um score baixo e invalidar a request. So se tiver algum jeito de forjar os token do captcha ae teria como scrappar so pelas requests, ou se isso tiver um App Mobile eu poderia ver quais requests eles usam la.

De toda maneira, a minha pergunta era uma API, como vi que a resposta é não vou ver o que faco para scrappar, eu so queria evitar de ter que scrappar pq ja é custo a mais (ja sou obrigado de cara a pagar Proxy)

Agora é a questao de achar a melhor ferramenta, eu ja achei varias botsaurus, playwirgth-stealth, undetected-chromedrive que rodam, mas so com headless=True, e isso precisa de um servidor mais parrudo para rodar com GUI. O ideal seria com headless=False, fica mais facil de escalar e dockerizar isso.

Preciso fazer o teste da sua com Windows, mas entre usar windows no servidor ou configurar linux com GUI, prefiro o linux com GUI.

meu ponto é que talvez as ferramentas botsaurus, playwirgth-stealth, undetected-chromedrive ou até mesmo seleniumbase que encontrei ontem, não sejam tão eficazes quanto utilizar emulação de dispositivo móvel com ADB. Eu nunca fiz dessa forma, eu achei essas soluções no canal de um alemão pyjudeme, que parece conseguir contornar o captcha de forma totalmente eficaz.

Entendi, eu senti na pele que não é eficiente mesmo, vou ver formas alternativas para ver se fica mais facil

Estou em uma situação similar.

Ao invés de utilizar headless, tente usar o xvfb. É necessário instalar o servidor xvfb na máquina. O próprio seleniumbase tem um wrapper para utilizar o xvfb, por exemplo:

from seleniumbase import Driver
from sbvirtualdisplay import Display

display = Display(size=(1920, 1080), visible=False)
display.start()
driver = Driver(uc=True, headed=True)

‘’’
Your crawler code
‘’’

display.stop()

Tudo que necessite de um ambiente gráfico dentro de display.start() e display.stop() será executado normalmente sem a necessidade de ter de fato uma gpu, pois o xvfb irá emular tudo isso.

Entretanto, essa solução é bem instável, ora funciona, ora não funciona.

2 Likes

eu nunca utilizei esse método, mas me parece bastante eficaz. A questão aqui que pra mim eu nao preciso de escalabilidade, então utilizar undetected-chromedriver ou seleniumbase já é o suficiente.

Boa, isso é uma boa opcao por enquanto, bem mais facil para dockerizar.

Vou fazer os testes aqui.

Acabei de ver o post e aparentemente estamos buscando coisas parecidas. A alternativa apresentada foi interessante, já fiz algumas automações utilizando Python e selenium. Conseguiu algo que possa contribuir com o código ainda mais?
Inclusive, buscando na internet, algumas ferramentas aparentam disponibilizar esse serviço de monitoramento de chat, se não tem uma API pública, será que eles fazem com scraping?

Rapaz, eu agora estou usando o seleniumbase em vez do undetected_chromedriver, mas a minha aplicação não é comercial. Eu andei fuçando o site e vi que tem um endpoint, no caso o serviço é da serpro, aliais, acredito que todo o portal de compras é da serpro. Pelo que entendi funciona da seguinte forma, quando você clica no botão de mensagens, no backend eles resolvem um captcha, devolvem esse captcha que é validado no endpoint e daí então retorna as mensagens de no máximo 5 por vez. Eu entrei no site da serpro e não achei nenhum serviço relacionado. Talvez se alguém obtiver sucesso com a serpro. Eu cheguei a mandar um email para eles, mas aí queriam cnpj , contato e blábláblá e depois me empurraram pro sistema de surporte, daí então eu deixei pra lá.

A partir de um contato, descobri que o serviço de uma dessas plataformas é um pouco precário. Sem entregar algumas mensagens e/ou com bastante atraso, provavelmente não utilizam uma API.
Por ser um pouco mais sensível e podendo haver instabilidade, não quero utilizar scraping para desenvolver uma aplicação comercial de monitoramento, mas para uso pessoal ajuda bastante!

Por enquanto eu consegui automatizar usando o endpoint das mensagens, unica parte chata é gerar o token, mas é muito mais rapido que pegar do html. (consegue pegar 20 mensagens de uma vez)

Agora meu problema é com o Login do acesso.gov, o captcha nele é aquele modo desafio, mesmo usando seleniumbase eles me detectam depois de algumas tentativas e aparecem com o desafio.

Ja chegou a automatizar o login?

como vc consegui gerar o token pra valida-lo no endpoint?Eu vi que eles utilizam uma outra api para gerar o token.

O acesso.gov, pelo que pesquisei, vc tem de entrar em contato com eles pra ter acesso a api, mas todo serviço de terceiro que utilizei , eles utilizam outro serviço de terceiro para quebra de captcha ou pedem para vc solucionar o captcha.

No meu caso de uso pessoal, eu nao passo pelo captcha pq possuo um certificado digital, então utilizo ele para fazer o login na automatização.

Tu precisa abrir dentro de uma pagina do comprasnet

Eu uso a https://cnetmobile.estaleiro.serpro.gov.br/comprasnet-web/public/compras

e rodar um js para gerar o token.

Depois so colocar o token gerado no campo captcha nas requisicoes do comprasnet

def generate_captcha_token():
    try:
        el = driver.find_element('css selector', '[data-hcaptcha-widget-id]')
    
        captcha_id = el.get_attribute('data-hcaptcha-widget-id')
        
        script = f"const {{ response }} = await hcaptcha.execute('{captcha_id}', {{ async: true }});return response;"
        result = driver.execute_script(script)
        
        return result
    except Exception as e:
        return ""
2 Likes

Obrigado, eu antes estava tentado simular a requisição para conseguir o token, ele me retornava, mas era um token inválido. Daí é falta de experiência minha. Não tenho de automatizar isso pra ninguém, talvez eu dê uma olhada no streamlit e crie um ambiente gráfico com as licitações que participo, vencedores, mensagens do pregoeiro e etc.

Eu tentei obter mais de 20 mensagens só que sem sucesso. O ruim é que para cada paginação você tem de gerar um token novamente.