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.