Executando verificação de segurança...
1
Kadu
4 min de leitura ·

[HELP] Como fazer deploy de uma API em Python que usa SELENIUM???

Fala turma blz? Recentemente, desenvolvi uma API utilizando Python, Selenium e FastAPI. Basicamente, essa API acessa uma conta no LinkedIn e coleta os dados de recomendações de um usuário. A ideia surgiu a partir de um colega que criou um portfólio e adicionou as recomendações que recebeu na rede social. No entanto, ele precisou fazer isso manualmente, e o conteúdo acabou ficando estático. Por isso, criei essa API para manter as informações sempre atualizadas.

Problema

a api em si está pronta e falta fazer o deploy, mas por envolver o selenium sempre dar erro no servidor

Erro aprensentado
```bash
Apr 14 10:53:58 PM  Traceback (most recent call last):
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/bin/uvicorn", line 8, in <module>
Apr 14 10:53:58 PM      sys.exit(main())
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
Apr 14 10:53:58 PM      return self.main(*args, **kwargs)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/click/core.py", line 1055, in main
Apr 14 10:53:58 PM      rv = self.invoke(ctx)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
Apr 14 10:53:58 PM      return ctx.invoke(self.callback, **ctx.params)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/click/core.py", line 760, in invoke
Apr 14 10:53:58 PM      return __callback(*args, **kwargs)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/main.py", line 403, in main
Apr 14 10:53:58 PM      run(
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/main.py", line 568, in run
Apr 14 10:53:58 PM      server.run()
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/server.py", line 59, in run
Apr 14 10:53:58 PM      return asyncio.run(self.serve(sockets=sockets))
Apr 14 10:53:58 PM    File "/opt/render/project/python/Python-3.8.1/lib/python3.8/asyncio/runners.py", line 43, in run
Apr 14 10:53:58 PM      return loop.run_until_complete(main)
Apr 14 10:53:58 PM    File "/opt/render/project/python/Python-3.8.1/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete
Apr 14 10:53:58 PM      return future.result()
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/server.py", line 66, in serve
Apr 14 10:53:58 PM      config.load()
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/config.py", line 471, in load
Apr 14 10:53:58 PM      self.loaded_app = import_from_string(self.app)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/uvicorn/importer.py", line 21, in import_from_string
Apr 14 10:53:58 PM      module = importlib.import_module(module_str)
Apr 14 10:53:58 PM    File "/opt/render/project/python/Python-3.8.1/lib/python3.8/importlib/__init__.py", line 127, in import_module
Apr 14 10:53:58 PM      return _bootstrap._gcd_import(name[level:], package, level)
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap>", line 991, in _find_and_load
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap_external>", line 783, in exec_module
Apr 14 10:53:58 PM    File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
Apr 14 10:53:58 PM    File "/opt/render/project/src/main.py", line 3, in <module>
Apr 14 10:53:58 PM      from scraping import get_Recommendations
Apr 14 10:53:58 PM    File "/opt/render/project/src/scraping.py", line 3, in <module>
Apr 14 10:53:58 PM      from driver import DRIVER, URL_BASE
Apr 14 10:53:58 PM    File "/opt/render/project/src/driver.py", line 26, in <module>
Apr 14 10:53:58 PM      DRIVER = Chrome(options=set_chrome_options())
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/chrome/webdriver.py", line 80, in __init__
Apr 14 10:53:58 PM      super().__init__(
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/chromium/webdriver.py", line 104, in __init__
Apr 14 10:53:58 PM      super().__init__(
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 286, in __init__
Apr 14 10:53:58 PM      self.start_session(capabilities, browser_profile)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 378, in start_session
Apr 14 10:53:58 PM      response = self.execute(Command.NEW_SESSION, parameters)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 440, in execute
Apr 14 10:53:58 PM      self.error_handler.check_response(response)
Apr 14 10:53:58 PM    File "/opt/render/project/src/.venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
Apr 14 10:53:58 PM      raise exception_class(message, screen, stacktrace)
Apr 14 10:53:58 PM  selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
Apr 14 10:53:58 PM  Stacktrace:
Apr 14 10:53:58 PM  #0 0x55c958c73fe3 <unknown>
Apr 14 10:53:58 PM  #1 0x55c9589b2d36 <unknown>
Apr 14 10:53:58 PM  #2 0x55c9589d9f4a <unknown>
Apr 14 10:53:58 PM  #3 0x55c9589d7a9b <unknown>
Apr 14 10:53:58 PM  #4 0x55c958a19af7 <unknown>
Apr 14 10:53:58 PM  #5 0x55c958a1911f <unknown>
Apr 14 10:53:58 PM  #6 0x55c958a10693 <unknown>
Apr 14 10:53:58 PM  #7 0x55c9589e303a <unknown>
Apr 14 10:53:58 PM  #8 0x55c9589e417e <unknown>
Apr 14 10:53:58 PM  #9 0x55c958c35dbd <unknown>
Apr 14 10:53:58 PM  #10 0x55c958c39c6c <unknown>
Apr 14 10:53:58 PM  #11 0x55c958c434b0 <unknown>
Apr 14 10:53:58 PM  #12 0x55c958c3ad63 <unknown>
Apr 14 10:53:58 PM  #13 0x55c958c0dc35 <unknown>
Apr 14 10:53:58 PM  #14 0x55c958c5e138 <unknown>
Apr 14 10:53:58 PM  #15 0x55c958c5e2c7 <unknown>
Apr 14 10:53:58 PM  #16 0x55c958c6c093 <unknown>
Apr 14 10:53:58 PM  #17 0x7fea58818fa3 start_thread
```

Tentativas de Soluções

- Fazer uma Imagem Docker (Dar o mesmo erro)
- Usar o Gekodriver (Firefox) ao inves do ChromeDriver

Repositorio Github

todo o codigo está nesse repositorio, tem duas brach a main e prodution.
A production está mais atualiza

Carregando publicação patrocinada...
2

Recentemente fiz um projeto que precisava resolver este problema, no meu caso eu fiz um RPA para automatizar o Service Now.
No seu codigo vi que vc usa o headless, pra mim isso não funcionava utilizando Docker, sugiro remover a linha:

chrome_options.add_argument("--headless")

So dei uma olhada superficial, vou tentar baixar o repo.

Outra sugestão é usar o Poetry.

1

O erro diz que o Selenium não consegui encontrar o executável do Chrome, provavelmente ele é instalado em um diretório do sistema que não é incluído na imagem do docker. Verifica se a biblioteca tem a opção de alterar o caminho de instalação do browser, altera ele para a raiz do seu projeto e incui no seu dockerfile.

1

utilize o comando nativo de instalação, n me recordo ao momento, mas ao invés de fazer a chamada no webdriver, irá baixá-lo e armazená-lo em cache no servidor.

1

Mais tarde eu tento fuçar melhor. Mas vendo o Dockerfile, você poderia colocar instruções do apt numa linha só, usando && e . Colocar várias instruções do mesmo comando acaba criando layers (procure sobre) a mais na imagem.

Mas talvez a bronca seja versão I compatível do Chrome do apt-get e ChromeDriver. É normal repositórios do Debian terem versões um mais antigas digamos, assim, mesmo utilizando um repo externo.

O que eu quero dizer... Talvez a versão mais recente do ChromeDriver seja com compatível com a versão mais recente do Chrome, digamos que 10.22. Pra Windows, possivelmente já tenha a 10.22, mas pra Debian esteja na versão 10.21. É minor version, mas pode fazer diferença.

Talvez você especificando a versão que você quer do Apt-get seja mais fácil de resolver. Na verdade, o mais correto é sempre especificar versões de qualquer coisa que você for usar.

Por exemplo.

apt-get install google-chrome-$CHROMEVERSION 
wget URL-do-ChromeDriver-$CHROMEVERSION
0

Eu sugiro, seja qual for o projeto, criar um mínimo de testes. Por exemplo ... Você já mete o louco de rodar FastAPI e Selenium. Isso acaba dificultando essa tua migração pra Docker. Por exemplo, o certo era ter um teste só pra saber se o selenium com o ChromeDriver tá de fato funcionando. Qualquer coisa, um print da página do Google, por exemplo. Só depois que tu pensaria em integrar com FastAPI.

Não é boa prática subir binários para repositórios, principalmente para projetos com muitos contribuidores, onde o número de commits tende a aumentar. Veja essa parte do Video do Akita https://youtu.be/6OokP-NE49k?t=1355 . Eu só fiz clone do projeto, mas a primeira coisa que eu fiz, foi deletar o ChromeDriver.

0