Ir para o conteúdo

Lab 13: Código final

Após todas as alterações de integração com o Orquestrador BotCity Maestro, o código final ficará semelhante a esse:

Projeto: Automação de busca e download de currículos

import os

from botcity.maestro import *
from botcity.web import Browser, By, WebBot
from webdriver_manager.chrome import ChromeDriverManager

BotMaestroSDK.RAISE_NOT_CONNECTED = False


def main():
    # Instancia do Orquestrador
    maestro = BotMaestroSDK.from_sys_args()
    execution = maestro.get_execution()

    # Usuário e senha para acessar o site
    username = maestro.get_credential(label="login_orangehrm", key="username")
    password = maestro.get_credential(label="login_orangehrm", key="password")

    # Instancia do bot
    bot = WebBot()

    # Configura o modo headless para False
    bot.headless = False

    # Define o navegador a ser utilizado
    bot.browser = Browser.CHROME

    # Instala a versão mais recente do ChromeDriver
    bot.driver_path = ChromeDriverManager().install()

    try:
        # Cria alerta de inicio da tarefa
        maestro.alert(
            task_id=execution.task_id,
            title="Iniciando",
            message="Iniciando a execução",
            alert_type=AlertType.INFO
        )

        # Acessa o site OrangeHRM
        bot.browse("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login")

        # Função que faz o login
        fazer_login(bot, username, password)

        # Busca e clica pela pagina de recrutamento
        aba_recruitment = bot.find_element(
            '#app > div.oxd-layout > div.oxd-layout-navigation > aside > nav > div.oxd-sidepanel-body > ul > li:nth-child(5) > a',
            by=By.CSS_SELECTOR)
        aba_recruitment.click()

        # Busca e clica no campo de status
        field_status = bot.find_element(
            '#app > div.oxd-layout > div.oxd-layout-container > div.oxd-layout-context > div > div.oxd-table-filter > div.oxd-table-filter-area > form > div:nth-child(1) > div > div:nth-child(4) > div > div:nth-child(2) > div > div > div.oxd-select-text--after > i',
            by=By.CSS_SELECTOR)
        field_status.click()

        # Aguarda 1 segundo e seleciona a opção "Intervier scheduled" com o teclado
        bot.wait(1000)
        bot.type_down()
        bot.type_down()
        bot.type_down()
        bot.type_down()
        bot.enter()

        # clicar no botão de pesquisa
        button_search = bot.find_element('#app > div.oxd-layout > div.oxd-layout-container > div.oxd-layout-context > div > div.oxd-table-filter > div.oxd-table-filter-area > form > div.oxd-form-actions > button.oxd-button.oxd-button--medium.oxd-button--secondary.orangehrm-left-space', by=By.CSS_SELECTOR)
        button_search.click()

        # Busca pelos candidatos
        lista_candidatos = bot.find_elements(
            '//*[@id="app"]/div[1]/div[2]/div[2]/div/div[2]/div[3]/div/div[2]/div[*]/div/div[7]/div/button[1]',
            by=By.XPATH)

        # Percorre a lista de candidatos
        for index, candidato in enumerate(lista_candidatos):
            # Busca pelo nome da pessoa candidata
            nome = bot.find_element(f'//*[@id="app"]/div[1]/div[2]/div[2]/div/div[2]/div[3]/div/div[2]/div[{index+1}]/div/div[3]/div', by=By.XPATH)
            nome = nome.text

            # Clica nas informações do candidato e aguarda 2 segundos
            candidato.click()
            bot.wait(2000)

            # Busca pelo botão de download do currículo e aguarda 2 segundos
            download = bot.find_element(
                '#app > div.oxd-layout > div.oxd-layout-container > div.oxd-layout-context > div.orangehrm-background-container > div > form > div:nth-child(5) > div > div > div > div:nth-child(2) > div > div',
                by=By.CSS_SELECTOR)
            bot.wait(2000)

            # Verifica se existe currículo e faz as ações necessárias
            if download:
                download.click()
                print("Baixando o currículo")
                bot.wait(2000)
                for arquivo in os.listdir():
                    if arquivo.endswith(".pdf") or arquivo.endswith(".docx"):
                        print(f"Baixou o currículo: {arquivo}")

                        # Cria log quando encontra o currículo
                        maestro.new_log_entry(
                            activity_label="controle_download",
                            values = {
                                "nome": nome,
                                "curriculo": arquivo
                            } 
                        )

                        # Sobe arquivo de resultado
                        maestro.post_artifact(
                            task_id=execution.task_id,
                            artifact_name=arquivo,
                            filepath=arquivo
                        )

                        # Aguarda 2 segundos e deleta o arquivo
                        print(f"Deletando o arquivo: {arquivo}")
                        bot.wait(2000)
                        os.remove(arquivo)
                        break

            else:
                # Cria log quando não encontra o currículo
                maestro.new_log_entry(
                    activity_label="controle_download",
                    values = {
                        "nome": nome,
                        "curriculo": "Não encontrado"
                    } 
                )

            bot.wait(2000)

            # voltar a pagina
            bot.back()
            bot.wait(2000)

        finish_status = AutomationTaskFinishStatus.SUCCESS
        finish_message = "Tarefa finalizada com sucesso"


    except Exception as e:
        # Grava uma captura de tela
        bot.save_screenshot("captura.png")

        # Define quais informações extras 
        # serão carregadas no Orquestrador BotCity Maestro
        tags = {
            "username": username,
            "password": password,
            }

        # Registre o erro
        maestro.error(
            task_id=execution.task_id,
            exception=e,
            tags=tags,
            screenshot="captura.png"
        )

        # Define status de finalização da tarefa com falha
        finish_status = AutomationTaskFinishStatus.FAILED
        finish_message = "Tarefa bot-recrutador finalizada com falha"


    finally:
        # Aguarda 3 segundos e fecha o navegador
        bot.wait(3000)
        bot.stop_browser()

        # Finaliza tarefa com o BotMaestro
        maestro.finish_task(
            task_id=execution.task_id,
            status=finish_status,
            message=finish_message
        )


def fazer_login(bot, username, password):
    element_user = "div.oxd-form-row:nth-child(2) > div:nth-child(1) > div:nth-child(2) > input:nth-child(1)"
    element_password = "div.oxd-form-row:nth-child(3) > div:nth-child(1) > div:nth-child(2) > input:nth-child(1)"
    element_button = ".oxd-button"

    bot.find_element(
        element_user,
        by=By.CSS_SELECTOR).send_keys(username)
    bot.find_element(
        element_password,
        By.CSS_SELECTOR).send_keys(password)
    bot.find_element(
        element_button,
        By.CSS_SELECTOR).click()



if __name__ == '__main__':
    main()

Desafio

Agora que passamos por várias integrações, o desafio é fazer suas próprias modificações no código para adicionar e gerenciar outras informações. Utilize a documentação para encontrar métodos e informações necessárias.