Modulo 023 – Integração Python – Automação Web (Parte 2)

 – Pegando Informações de Elementos dentro de Elementos

Nessa aula vamos percorrer todas as imagens dos cursos que estão na página e extrair o link para onde essas imagem nos redirecionam.
Para selecionar as imagens dos cursos temos que procurar algum atributo como ID, Classe, que pareça único desse tipo de imagem e que se repita em todas as imagens. E você também deve se perguntar aonde está o link que você quer extrair. Nós sabemos que o link está em <a> que é parent de <img>. Em <a> também não tem nenhum atributo que se repita em todas as outras imagens. Então podemos analisar os parents de <a> que são <figure> e <div>. <figure> não é uma tag muito comum e se repete nas outras imagens, e
<div> possui a classe “wp-block-image” e também se repete nas outras imagens.

Estas 2 são boas opções, mas neste exemplo vamos testar com a tag <figure>. Vamos pegar todas as tags <figure> do site.

 lista_elementos = navegador.find_elements(By.TAG_NAME, "Figure"
 print(len(lista_elementos)) 
____________________
 6 

Todos os elementos com a tag <figure> são selecionados e armazenados na lista lista_elementos. Para saber se essa lista é a ideal para o nosso caso, devemos verificar se o tamanho dela é igual a quantidade de imagens nas quais estamos interessados. O tamanho é 6, então ela é perfeita. Agora precisamos extrair o link que está na tag <a> de cada imagem, além disso sabemos também que a tag <a> é child de <figure>. Para isso, primeiro temos que percorrer essa lista.

 lista_elementos = navegador.find_elements(By.TAG_NAME, "Figure") #Lista de figures 
 for elemento in lista_elementos: 
    link = elemento.find_element(By.TAG_NAME, "a").get_attribute("href) 
    print(link) 

• Usando o .find_element em um elemento, ele só irá fazer sua busca dentro do elemento, enquanto que usando o .find_element no navegador sua busca será na página inteira.
Essa linha de código pega o atributo href da tag <a> que está dentro do elemento percorrido.
• Retornou um erro, porque não foi possível extrair o link da última imagem. Não achou o elemento <a>.

Não foi encontrado o elemento <a> na imagem do powerpoint impressionador, como podemos ver abaixo. Ou seja, a imagem está sem link.
Para contornar o erro, podemos usar o try e o except.

 lista_elementos = navegador.find_elements(By.TAG_NAME, "Figure"#Lista de figures 
 for elemento in lista_elementos: 
    try
        link = elemento.find_element(By.TAG_NAME, "a").get_attribute("href) 
    print(link) 
    except
        continue 

• Usando o try e o except, ele vai tentar pegar o link, mas se alguma das imagens estiver sem link, ele vai pular e passar para o próximo.

– Preenchendo formulários com o Selenium (botões e caixas de seleção)

Nesta aula vamos começar a usar o selenium para interagir com formulários em site. Para isso, vamos pegar uma página que tem a maioria dos tipos de formulários e aprender a interagir com cada elemento.
• O arquivo “Preenchendo Formularios.ipynb” e “formulario.html” devem estar na mesma pasta.

Na parte inicial do nosso código temos os códigos abaixo para configurar o Selenium e acessar o formulário com o qual queremos interagir.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
                                 
 servico = Service(ChromeDriverManager().install()) 
 navegador = webdriver.Chrome(service=servico) 

• Inicializa o nosso navegador do Selenium

 import os 
              
 caminho = os.getcwd() 
 arquivo = caminho + r"\formulario.html" 
 navegador.get(arquivo) 

Usa o caminho do arquivo que estamos utilizando (Preenchendo Formularios.ipynb) para abrir o arquivo formulario.html.
Nesta aula vamos começar a usar o selenium para interagir com formulários em site. Para isso, vamos pegar uma página que tem a maioria dos tipos de formulários e aprender a interagir com cada elemento.
Nesta primeira parte vamos interagir com o botão “clique em mim” usando o método que já vimos anteriormente .click(). Clicando em inspecionar, podemos ver que a maioria dos elementos não possui classe nem ID para selecionarmos, então vamos usar o XPATH como método de seleção para todos os elementos.

Agora vamos clicar no primeiro botão.

 navegador.find_element(By.XPATH, '/html/body/form/input[1]').click() 

Após rodar o código, ele clicou no botão e esse botão
disparou um alerta, um pop-up. Você pode interagir com esse pop-up, clicando em
OK, alguns pop-ups você também pode clicar em CANCELAR.
Por enquanto vamos clicar em OK usando o Selenium.

 navegador.find_element(By.XPATH, '/html/body/form/input[1]').click() 
 alerta = navegador.switch_to.alert 
 alerta.accept() 

• Nos dá como resposta o pop-up (alerta).
• Aceita o alerta que aparece quando clicamos no botão “Clique em mim”.
• switch_to manda o navegador alternar para um frame, ou nova aba ou alerta. Nesse caso, estamos alternando para um alerta.

Com esse código, ele clica no botão e logo depois confirma o alerta. Isso acontece tão rápido que é muito provável que quando você for no seu navegador, o alerta não esteja mais lá.

Agora vamos ver alguns botões com características diferentes das características desse primeiro botão. Alguns desses botões são o checkbox e o radiobutton. O checkbox permite selecionar vários deles ao mesmo tempo enquanto que o radio button só permite selecionar 1 opção por vez.

Esses e outros botões que veremos são diferentes porque além de clicar neles ou preencher com alguma informação, é possível também extrair informações desses botões. Para extrairmos as informações dos botões usaremos os 3 argumentos:
• .text
• .get_attribute(“value”)
• .is_selected()
Vamos ver como funciona com os checkboxes.
Vamos copiar o XPATH do nosso segundo checkbox para clicarmos nele.

 # clicar no botão 
 navegador.find_element(By.XPATH, '/html/body/form/input[2]').click() 

 # verificar o valor do botão 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[2]').is_selected() 
 print(valor) 
____________________
 True 

• Verifica se o botão está selecionado, em caso positivo retorna True, e se não estiver selecionado retorna False.

Cada vez que você clicar no botão, o estado dele mudará. Você pode fazer isso também
para o primeiro checkbox, basta copiar o XPATH dele e usar no seu código.

– Campos de Texto Personalizado e Datas

Agora vamos continuar a nossa interação com o formulário a partir de onde paramos na última aula. Vamos ver agora como funciona um campo de texto padrão. Por exemplo o campo:
Qual seu time? ___________    <input type="text"> == $0 

Vamos copiar o XPATH desse elemento e preencher com a palavra “Vasco”.

 # preencher 
 navegador.find_element(By.XPATH, '/html/body/form/input[16]').send_keys("Vasco"

Vamos extrair o valor que está dentro desse campo (input)

 valor = navegador.find_element(By.XPATH, '/html/body/form/input[16]').get_attribute("value"
 print(valor) 
________________
 Vasco 

Você pode se perguntar por que retornou o valor exato se não estou vendo o atributo “value” no código html deste elemento. Para os elementos <input>, usar .get_attribute(“value”) extrai o valor dentro deles. O input nada mais é que um elemento de um formulário que permite a entrada de dados por parte do usuário, e ele pode aparecer de diversas formas como checkbox, radio button, campo de texto, etc. Lembrando que nos botões de seleção não usamos .get_attribute(“value”), mas sim .is_selected() para saber se o botão está selecionado ou não.

Agora vamos adaptar isso para o nosso botão de seleção de cores.
Selecione o vermelho por RGB 232 33 33
Vamos copiar o XPATH e verificar qual cor foi selecionada

 # verificar qual a cor foi selecionada 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[4]').get_attribute("value"
 print(valor) 
____________________
 #894d4d 

• Código hexadecimal da cor – É o código da cor selecionada no padrão hexadecimal.

Podemos ver que para preencher este elemento devemos passar o código hexadecimal de uma cor. Vamos testar com #3145DD que é um tom de azul.

 # preencher a cor 
 navegador.find_element(By.XPATH, '/html/body/form/input[4]').send_keys('#3145DD'

Você também pode usar um conversor online de RGB para HEX. Fazendo a conversão de RGB 232 33 33 para HEX é #e82121

 # preencher a cor 
 navegador.find_element(By.XPATH, '/html/body/form/input[4]').send_keys('#E82121'

Alguns botões você precisará visualizar em que formato eles estão exibindo a informação e preencher de acordo com esse formato. Um exemplo disso é o botão de data.
Qual é o aniversario da sua cidade? dd/mm/aaaa   <input type="date"> flex == $0 

Por exemplo, vamos copiar o XPATH desse elemento e passar a data 15/02/1994 para ele.

 navegador.find_element(By.XPATH, '/html/body/form/input[6]').send_keys('15/02/1994'

O importante é você tentar identificar que tipo de formato cada input aceita. Para isso você precisa testar e depois verificar se a informação foi preenchida corretamente, caso contrário teste outro formato.

 # pegar o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[6]').get_attribute("value"
 print(valor) 
___________________
 1994-02-15 

Perceba que o formato de preenchimento é dd/mm/aaaa enquanto que o formato na hora de pegar o valor do input é aaaa-mm-dd
Se passarmos o formato que obtivemos ao pegar o valor (aaaa-mm-dd) e tentarmos preencher esse input, será que funciona? Nesse caso não funciona

– Campos com Várias Informações e de Arquivos

Na última aula fizemos o preenchimento de um campo de data. E se quiséssemos preencher um campo com data e horário específico? Como faríamos?

Que dia e que horas você nasceu? dd/mm/aaaa --:--   <input type="datetime-local"> flex == $0 

O primeiro passo é você selecionar uma data e um horário, e verificar o formato em que ficaram as informações neste campo. Porque provavelmente esse é o formato que você terá que usar quando for preencher este campo. Agora vamos copiar o XPATH deste input e tentar preencher este campo.

Que dia e que horas você nasceu? 08/03/2022 21:33

 # preenchendo 
 navegador.find_element(By.XPATH, '/html/body/form/input[7]').send_keys('15/02/1994 14:15'

Que dia e que horas você nasceu? 15/02/1994 21:33  

Podemos perceber que somente a data foi modificada, o horário não foi alterado. Na verdade existem 2 informações dentro desse campo, e não apenas uma. Então teremos que preencher 2 informações. Para isso vamos usar a tecla TAB.

 # preenchendo 
 from selenium.webdriver.common.keys import Keys 
                  
 navegador.find_element(By.XPATH, '/html/body/form/input[7]').send_keys('17/10/1994', Keys.TAB, '23:50'

Que dia e que horas você nasceu? 17/10/1994 23:50 

• Permite apertar uma tecla do seu teclado em um campo específico

Para pegar o valor desse campo, teremos que fazer como na imagem abaixo.

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[7]').get_attribute("value"
 print(valor) 
_________________________
 1994-10-17T23:50 

Agora vamos ver como funciona o campo de anexar o arquivo.
"Nenhum arquivo selecionado"   <input type="file"> == $0 

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[8]').get_attribute("value"
 print(valor) 

• Como não tem nenhum arquivo selecionado, não printou nenhum valor.

A partir do momento que um arquivo é selecionado, o nome desse arquivo aparece do lado do botão. Vamos ver qual o valor que está armazenado nele.

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[8]').get_attribute("value"
 print(valor) 
_________________________
 C:\fakepath\formulario.html 

Agora vamos preencher o campo de anexar arquivo.
Escolher Arquivo Calendario.pdf

 # pegando o valor 
 navegador.find_element(By.XPATH, '/html/body/form/input[8]').send_keys(r'C:\Users\Joaol\Downloads\Calendario.pdf') 

Outra forma de preencher esse campo é como no código abaixo.

 # preenchendo 
 caminho = os.getcwd() 
 arquivo = caminho + r"\formulario.html" 
               
 navegador.find_element(By.XPATH, '/html/body/form/input[8]').send_keys(arquivo) 

Escolher Arquivo formulario.html

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[8]').get_attribute("value"
 print(valor) 
_________________________
 C:\fakepath\formulario.html 

• fakepath aparece no caminho, porque o navegador não armazena no site o caminho
do seu computador, ele só armazena o nome do arquivo.

– Exercitando em outros campos

Nesta aula vamos continuar preenchendo os campos do nosso formulário.
Selecione um mês e um ano ----- de ----   <input type="month"> flex == $0 
Selecione um mês e um ano junho de 2022 

Vamos começar preenchendo os campos que faltam! Primeiro selecionamos uma data para verificar o formato, e depois de copiar o XPATH dele, vamos tentar preencher esse campo com o mesmo formato.

 navegador.find_element(By.XPATH, '/html/body/form/input[9]').send_keys('janeiro de 1980'

Selecione um mês e um ano janeiro de 2022

Aconteceu o mesmo problema que tinha acontecido com o campo de data e hora. Ele preencheu o primeiro valor, mas não preencheu o segundo valor. Provavelmente teremos que usar a tecla TAB para modificar o segundo valor.

 navegador.find_element(By.XPATH, '/html/body/form/input[9]').send_keys('janeiro', Keys.TAB, '1980'

Selecione um mês e um ano janeiro de 1980

O valor foi preenchido corretamente. Agora vamos pegar o valor desse campo.

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[9]').get_attribute("value"
 print(valor) 
_________________________
 1980-01 

• Perceba que o formato do valor que pegamos é (aaaa-mm)

Agora vamos ver alguns campos padrões de texto, mas com características específicas. O próximo campo só aceita números.

Só inputs numéricos aqui ______   <input type="number"> == $0 

Vamos copiar o XPATH desse elemento e depois preencher esse campo.

 navegador.find_element(By.XPATH, '/html/body/form/input[10]').send_keys("123456"

Como podemos ver, o valor foi preenchido corretamente. Um método muito útil que serve também para os outros campos é o .clear() que serve para você limpar o campo de informações que foram preenchidas anteriormente. Você pode usar esse método para garantir que um determinado campo esteja limpo antes de você inserir novas informações.

 navegador.find_element(By.XPATH, '/html/body/form/input[10]').clear() 

O próximo campo é o campo de senha.

Cuidado para não revelar sua senha! ______   <input type="password"> == $0 

Vamos copiar o XPATH desse elemento e depois preencher esse campo.

 # preencher 
 navegador.find_element(By.XPATH, '/html/body/form/input[11]').send_keys("123456"

Como podemos ver, o campo foi preenchido.
 ****** 

Agora vamos pegar o valor desse campo.

 # pego o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[11]').get_attribute('value')
 print(valor) 
________________
 123456 

Podemos ver que o valor que pegamos foi o mesmo valor que preenchemos o campo.

O próximo botão é o radio button. O procedimento para usar esse botão é o mesmo de usar o checkbox.

Com Radio buttons só é possível escolher uma  opção por vez, selecione a opção do meio 〇〇〇  <input type="radioname="01"> == $0 

Vamos copiar o XPATH do terceiro botão e depois clicar nele.

 navegador.find_element(By.XPATH, '/html/body/form/input[14]').click()  ◯◯⚫

Um erro que pode acontecer quando você tentar selecionar um radio button é ele não selecionar o botão mesmo o seu código estando correto. Quando isso acontecer, reinicie o seu navegador e tente rodar o seu código novamente. Provavelmente isto irá resolver o problema. Relembrando que o método .is_selected() verifica o estado do botão, se ele está selecionado ou não. Podemos ver ao lado que somente o terceiro botão está selecionado.

#Verificando se os botões estão selecionados 
#botão 1 
 navegador.find_element(By.XPATH, '/html/body/form/input[12]').is_selected() 
_________________
 False 

#botão 2 
 navegador.find_element(By.XPATH, '/html/body/form/input[13]').is_selected() 
_________________
 False 

#botão 3 
 navegador.find_element(By.XPATH, '/html/body/form/input[14]').is_selected() 
_________________
 True 

O próximo campo é o de horas. Vamos selecionar uma hora qualquer para verificar qual o formato desse campo.
Que horas são? 23:17   <input type="time"> flex == $0 

Vamos copiar o XPATH desse campo para tentar preenchê-lo.

 navegador.find_element(By.XPATH, '/html/body/form/input[17]').send_keys('15:15'

Que horas são? 15:15

Vamos agora para o campo da semana. Vamos selecionar uma semana qualquer para verificar qual o formato do campo.

Semana? Semana 11, 2022   <input type="week"> flex == $0 

Vamos copiar o XPATH desse campo para tentar preenchê-lo.

 navegador.find_element(By.XPATH, '/html/body/form/input[18]').send_keys('Semana 17', '2005'

Podemos ver que não conseguimos preencher esse campo com esse formato. Vamos tentar outro formato.

 navegador.find_element(By.XPATH, '/html/body/form/input[18]').send_keys('17, 2005'

Só foi preenchida a semana, o ano não foi preenchido. Provavelmente precisaremos de uma tecla TAB para preencher.

 navegador.find_element(By.XPATH, '/html/body/form/input[18]').send_keys('17', keys.TAB, '2005'

Também não funcionou. Vamos testar agora sem o TAB.

 navegador.find_element(By.XPATH, '/html/body/form/input[18]').send_keys('17', '2005'

Semana? Semana 17, 2005

Agora funcionou. É muito importante você testar um formato diferente quando o formato que você estiver usando não der certo, porque isso vai te deixar mais independente, e quando você encontrar um campo diferente, você saberá avaliar uma forma de preencher esse campo.
Agora vamos ver um bloco de texto. Vamos preencher este campo para verificar o formato e vamos também copiar o XPATH dele.

Olá
Meu nome é Lira
Ta aprendendo python?

 <textarea id="story" name="story" rows="5" cols="33"></textarea> == $0 

 navegador.find_element(By.XPATH, '//*[@id="story"]').clear() 
 navegador.find_element(By.XPATH, '//*[@id="story"]').send_keys("Olá", Keys.ENTER, 'Meu nome é Lira', Keys.ENTER, 'Value, Tmj'

– Campos de Arrastar

Agora vamos ver como fazer para editar os campos de slider.

 <input type="rangemin="0max="100"> == $0 

O slider (range) pode variar de 0 a 100, como podemos ver. O primeiro passo é copiar o XPATH desse elemento para mostrar como pegar o valor desse campo.

 # pegar o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[15]').get_attribute('value'
 print(valor) 
___________________
 50 

Se movermos o slider para perto do final, esse valor será muito próximo de 100. Se movermos totalmente para o final, será 100. Mas se movermos totalmente para o início, o valor será zero.

E se usarmos o método .clear() no slider, o que acontece?

 elemento = navegador.find_element(By.XPATH, '/html/body/form/input[15]'
 elemento.clear() 

 # pegar o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/input[15]').get_attribute('value'
 print(valor) 
___________________
 50 

Quando usamos o método .clear() no slider, a posição do slider volta à posição padrão que é o meio (50). Agora teremos que mover o slider para a posição 70. Se você mexer a seta do seu teclado, o slider se move de 1 em 1. Podemos usar o método .clear() antes de mover o slider, para garantir que a posição inicial do slider seja sempre 50. E o número de vezes que precisamos pressionar a seta do teclado para mover o slider é igual a diferença entre a posição desejada e a posição inicial do slider.
Vamos fazer isso com auxílio do for.

 # preencher o valor 
 elemento = navegador.find_element(By.XPATH, '/html/body/form/input[15]'
              
 elemento.clear() #Garante que a posição inicial do slider é 50
 for i in range(70 - 50): 
     elemento.send_keys(Keys.ARROW_RIGHT) 

Nesse caso, para ir para da posição 50 para 70, precisamos pressionar a seta para a direita do teclado, por isso ARROW_RIGHT

– Campos de Lista de Valores

Nesta aula vamos aprender como trabalhar com os dropdowns (lista de valores). Essas listas são listas que a princípio não tem um valor específico, que precisa que você clique nela e escolha uma opção.

 <select> == $0 
     <option value="a">A</option> 
     <option value="b">B</option> 
     <option value="c">C</option> 
 /<select> 

No caso dessa lista, no código da página já temos as 3 opções. Porém em listas dinâmicas, as opções só irão aparecer ao clicar na lista. Vamos copiar o XPATH desse elemento para selecioná-lo. Vamos também tentar enviar um valor a esse elemento.

 # preencher o valor 
 navegador.find_element(By.XPATH, '/html/body/form/select[1]').send_keys('C'

• Podemos ver que a letra C foi selecionada.
• Mostra o valor da opção selecionada, nesse caso letra C.

 # pegando o valor 
 valor = navegador.find_element(By.XPATH, '/html/body/form/select[1]').get_attribute('value')
print(valor) 
__________
 c 

Quando a lista for uma lista de formulário, o .send_keys() vai funcionar. Mas nem toda lista é de formulário, e para esses casos você terá que clicar e selecionar a opção dentro dessa lista. Vamos ver como fazer isso.

 # clicando para selecionar 
 navegador.find_element(By.XPATH, '/html/body/form/select[1]').click() 

Quando clicamos no elemento, ele abre a lista de opções. Pode ser que você não consiga visualizar essa lista aberta, pois ao mudar de página, ela se fecha. Dado que a lista está aberta, agora você pode selecionar um dos 3 itens.

 <select> == $0 
     <option value="a">A</option> 
     <option value="b">B</option> 
     <option value="c">C</option> 
 /<select> 

Agora que a lista está aberta, para selecionar uma opção devemos copiar o XPATH da opção que queremos.

 # selecionando manualmente 
 import time 
 navegador.find_element(By.XPATH, '/html/body/form/select[1]').click()
time.sleep(0.5) #espera meio segundo 
 navegador.find_element(By.XPATH, '/html/body/form/select[1]/option[3]').click() 

O que esse código faz é clicar na lista, então a lista é aberta, espera meio segundo, e então seleciona a opção 3 (letra C).

– Usando o Select e discussão sobre erros no Selenium

Na aula passada aprendemos 2 métodos de como interagir com listas suspensas (dropdowns), usando o .send_keys() e o .click(). Nesta aula veremos como interagir com essas listas usando o Select.

 <select> == $0 
     <option value="a">A</option> 
     <option value="b">B</option> 
     <option value="c">C</option> 
 /<select> 

A lista suspensa com a qual estávamos trabalhando na aula passada e vamos trabalhar nessa aula é um elemento do tipo <select>. Nem todo elemento do tipo <select> será possível interagir através dos métodos que aprendemos até aqui. Pensando nisso, o Selenium criou uma forma específica de interagir com elementos desse tipo.
Vamos ver como selecionar a lista suspensa usando essa forma.

 from selenium.webdriver.support.select import Select 
                  
 elemento = navegador.find_element(By.TAG_NAME, 'select'
 elemento_select = Select(elemento) 

• Importa o Select.
• Usamos o .find_element para selecionar o elemento pela tag <select>, porque sabemos que só existe 1 elemento desse na página, e porque esse método é para elementos do tipo <select>.
• Aplicamos a classe Select ao elemento. E agora conseguimos interagir com o elemento_select através de métodos diferentes.

Por exemplo, vamos usar alguns desses métodos e ver o que acontece.
1) .select_by_index()

 elemento_select.select_by_index(0

O .select_by_index() seleciona o elemento pelo índice. Nesse caso, o índice zero, referente ao primeiro elemento da lista (letra A).

 elemento_select.select_by_index(1

Nesse caso, selecionamos pelo índice 1, referente ao segundo elemento da lista (letra B).

 elemento_select.select_by_index(2

Nesse caso, selecionamos pelo índice 2, referente ao terceiro elemento da lista (letra C).

Podemos também usar outras formas de seleção como .select_by_value() e .select_by_visible_text(). E é importante saber que o valor de um elemento não é necessariamente o texto que está aparecendo para você, por isso existem esses 2 métodos diferentes.

 <select> == $0 
     <option value="a">A</option> 
     <option value="b">B</option> 
     <option value="c">C</option> 
 /<select> 

Nesse caso, o texto visível está com letra maiúscula enquanto que o valor do elemento está com letra minúscula.
Por exemplo, vamos usar alguns desses métodos e ver o que acontece.

 elemento_select.select_by_value('a'

O .select_by_value() seleciona o elemento pelo valor do elemento. Nesse caso, o valor ‘a’, referente ao elemento de letra A.

 elemento_select.select_by_value('b'

Nesse caso, selecionamos o valor ‘b’, referente ao elemento de letra B.

 elemento_select.select_by_value('c'

Nesse caso, selecionamos o valor ‘c’, referente ao elemento de letra C.

3) .select_by_visible_text()

 elemento_select.select_by_visible_text('A'

O .select_by_visible_text() seleciona o elemento pelo texto visível do elemento. Nesse caso, o texto ‘A’, referente ao elemento de letra A.

 elemento_select.select_by_visible_text('B'

Nesse caso, selecionamos o texto ‘B’, referente ao elemento de letra B.

 elemento_select.select_by_visible_text('C'

Nesse caso, selecionamos o texto ‘C’, referente ao elemento de letra C.

Nós estamos trabalhando com uma lista suspensa que permite a seleção de um único item, mas algumas listas suspensas permitem a seleção de mais de um item. Para esses casos existem alguns métodos que podem ser mais interessantes, como por exemplo:

Desmarca os itens selecionados
.deselect_all()
.deselect_by_index()
.deselect_by_value()
.deselect_by_visible_text()

 print(elemento_select.is_multiple) 
___________________
 none 

• Significa que não é um elemento múltiplo.
• O método .is_multiple verifica se esse é um elemento múltiplo, ou seja, se ele permite selecionar mais de um item.

Existem outros métodos também para verificar qual item foi selecionado dentro da lista.

 # ler o elemento selecionado 
 item = elemento_select.first_selected_option 
 print(item.get_attribute('value')) 
________________________
 a 

• .first_selected_option não retorna o valor do elemento selecionado. Retorna o próprio elemento que foi selecionado.
• A partir disso, podemos extrair o atributo desse elemento independentemente de quem ele for. Nesse caso extraímos o valor dele, que é ‘a’.

 # ler o item selecionado 
 lista_itens = elemento_select.all_selected_options 
 print(lista_itens) 
_________________
 [<selenium.webdriver.remote.webelement.WebElement (session="6c558e556921e135c0548455ed72e91d", element="e7fd38b5-e430-4bca-9935-943cde605748")>] 

• Retorna uma lista com todos os elementos selecionados, mas como a nossa lista suspensa permite selecionar apenas um elemento, será retornada uma lista com apenas 1 elemento.
• Lista com apenas 1 elemento.

A diferença desse método para o método anterior é basicamente a mesma diferença entre o .find_elements() e o .find_element(). Vamos ver abaixo como pegar o valor desse elemento.

 # ler o elemento selecionado 
 lista_itens = elemento_select.all_selected_options 
 print(lista_itens[0].get_attribute("value"))
__________________
 a 

Devemos lembrar que o método .all_selected_options nos retorna uma lista, e para pegar o valor dentro da lista devemos usar o nome da lista e o índice do elemento da lista, mesmo que a lista só contenha 1 único elemento.

 # ler o elemento selecionado 
 lista_itens = elemento_select.all_selected_options 
 print(lista_itens[0].text) 
__________________
 A 

– ActionChains e Dropdowns Especiais

Nessa aula vamos trabalhar com uma forma diferente de dropdown. Esse tipo de dropdown você pode encontrar em muitos sites, que é basicamente um dropdown simulado, diferente de um dropdown de formulário. Por exemplo:

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install()) 
 navegador = webdriver.Chrome(service=servico) 

 import os 
                 
 caminho = os.getcwd() 
 arquivo = caminho + r"\Pagina Hashtag.html" 
 navegador.get(arquivo) 

• Menu dropdown simulado. Esse menu aparece quando deixamos o mouse sobre o
botão “OUTROS CURSOS”. É diferente do dropdown de formulário.

Nesse caso, não podemos clicar em “outros cursos” para abrir a lista, e depois clicar na lista, pois se clicarmos em “outros cursos”, ele nos redirecionará para outra página.
Se quiséssemos, por exemplo, clicar em “Curso de SQL”, teríamos que pegar o mouse, passar em cima de “OUTROS CURSOS” e depois colocar em cima de “Curso de SQL” e aí clicar. Como ele é um dropdown simulado e tem um comportamento diferente, algumas das formas que aprendemos antes não irão funcionar. Mas nessa aula veremos o ActionChains que vai facilitar demais essa tarefa.

Como faríamos para selecionar o “Curso de SQL” normalmente?

• Botão OUTROS CURSOS com link associado a ele.
• <ul> é uma lista em html.
• Dentro da lista <ul>, temos as <li> que são os itens dessa lista. O primeiro item dessa lista é o elemento “Curso de SQL”.

Como estamos interessados em selecionar o elemento “Curso de SQL”, vamos copiar o XPATH dele e vamos tentar clicar.

 navegador.find_element(By.XPATH,'//*[@id="menu-item-17042"]/a').click() 
---------------------
 ElementNotInteractableException 

• Elemento não interagível, ou seja, ele encontrou o elemento, mas alguma coisa na página está nos impedindo de interagir com este elemento.

Nós não conseguimos clicar neste elemento. Mas você tem que se perguntar qual o seu objetivo com este elemento. Se o seu objetivo é clicar neste elemento para navegar para a página do Curso de SQL, você pode copiar o link desta página. Você pode perceber também que o link é um parâmetro href deste elemento, e como já selecionamos este elemento, podemos pegar o atributo href dele e navegar até o link associado a ele.

 link = navegador.find_element(By.XPATH,'//*[@id="menu-item-17042"]/a').get_attribute('href'
 navegador.ged(link) 

Essa é uma das opções, mas nem sempre o elemento que você está tentando clicar tem o atributo href. Nesse caso, precisamos pegar o mouse e colocar ele em cima do botão “OUTROS CURSOS” para desta forma a lista aparecer e o item “Curso de SQL” se tornar um
elemento interagível ou interactable. Para fazer isso, usaremos um elemento chamado ActionChains (documentação), que simula ações do seu mouse dentro do seu navegador, sem usar o seu mouse.

 from selenium import ActionChains 
            
 menu = navegador.find_element(By.XPATH,'//*[@id="menu-item-dropdown-16313"]/a'
 item = navegador.find_element(By.XPATH,'//*[@id="menu-item-17042"]/a'
            
 # colocar o mouse encima do menu 
 ActionChains(navegador).move_to_element(menu).perform() 
            
 # clicar no item 
 item.click() 

• Seu navegador como parâmetro.
• Ação que você quer simular. Nesse caso, mover o mouse até um elemento.
• Elemento no qual a ação será realizada. Nesse caso, menu.
• .perform() realiza a ação. E vem sempre no final.

Podemos ver que funcionou e que fomos redirecionados para a página do Curso de SQL. Em algumas páginas, após o ActionChains simular a ação de mover o mouse para determinado elemento, pode ser que demore um pouco para aparecer o menu. Nesse caso, podemos usar o time.sleep() entre os comandos de colocar o mouse em cima e o de clicar no item.

– Alertas no Selenium

Nessa aula, vamos aprender a trabalhar com alertas. Embaixo do vídeo dessa aula tem o link para baixar os arquivos necessários, que nesse caso é a página alertas.html. A parte inicial do código é bem parecida com o código das aulas anteriores, com a diferença de que agora estamos abrindo a página “alertas.html”.

Importações

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install()) 
 navegador = webdriver.Chrome(service=servico) 

Abrindo “alertas.html” que está na mesma pasta desse código

 import os 
                 
 caminho = os.getcwd() 
 arquivo = caminho + r"\alertas.html" 
 navegador.get(arquivo) 

Rodando esse código, a página “alertas.html” será aberta. Cada botão da página aciona um alerta, conforme mostrado abaixo.

É importante destacar a diferença entre um alerta e um pop-up. Um pop-up é um elemento da página que você consegue encontrar ao inspecionar a página. Já um alerta você não consegue inspecionar porque ele não é um elemento da página, mas sim do seu navegador.
Agora vamos interagir com os alertas. Para isso, vamos precisar copiar o XPATH de cada botão para clicar em cada um deles e fazer os alertas aparecerem. E depois, vamos ver como fazer a interação para cada tipo de alerta.

 # selecionar um alerta 
 navegador.find_element(By.XPATH, '/html/body/div[1]/input').click() 

# forma simples 
 alerta = navegador.switch_to.alert 
 alerta.accept() 

• O método .switch_to permite o navegador migrar para outros elementos como alerta, por exemplo. E com isso, você poderá interagir com esses elementos.
• Tipo de elemento para o qual o navegador migrará. Nesse caso, alerta.
• Confirma o alerta, clicando em OK.

 # forma "completa" 
 from selenium.webdriver.common.alert import Alert 
                 
 alerta = Alert(navegador) 
 alerta.accept() 

• Seu navegador como parâmetro, para que a função pegue o alerta do seu navegador.
• Confirma o alerta, clicando em OK.

Como você pode ver, existem duas formas de selecionar um alerta, a forma simples e a forma “completa”. As 2 formas funcionam, e você pode usar a forma que preferir.

2) Alerta de Confirmação

 navegador.find_element(By.XPATH, '/html/body/div[2]/input').click() 
                   
 alerta = Alert(navegador) 

Lembrando que você deve selecionar o alerta a cada alerta novo que surgir na página.

 # aceitar 
 alerta.accept() 

 # cancelar 
 alerta.dismiss() 

.accept() confirma o alerta.
.dismiss() cancela o alerta.
O que vai acontecer depois disso é o site que vai determinar.

Podemos também pegar o texto de um alerta, como podemos ver abaixo. Podemos usar esse mesmo alerta de confirmação clicando no botão dele para o alerta ser aberto.

 navegador.find_element(By.XPATH, '/html/body/div[2]/input').click() 
                        
 alerta = Alert(navegador) 
 texto = alerta.text 
 print(texto) 
________________________
 Quer confirmar a emissão da NF? 

3) Alerta de Input

 navegador.find_element(By.XPATH, '/html/body/div[2]/input').click() 
                   
 alerta = Alert(navegador) 

Preenche o input do Alerta

 alerta.send_keys('123123'

Não estamos vendo a informação que enviamos para o input do alerta ser preenchida.
Isso ocorre por causa de algum bug do Selenium para o Chrome ou do Chrome para o
Selenium. E como é um bug que não atrapalha o funcionamento do código, eles tiraram
a prioridade para a resolução desse erro.
Podemos ver ao lado que a informação que preenchemos usando o .send_keys() é a
mesma que foi exibida na página.

– Trabalhando com Diferentes Abas e Janelas

Nessa aula, vamos trabalhar com novas abas. Em algumas automações que vamos fazer, quando clicarmos em um link, esse link será aberto em uma nova aba ou em uma nova janela. E vamos ver como lidar com isso. A estrutura é parecida com a que fizemos na aula de alertas.
Lembrando que usaremos a página da hashtag que fizemos download dos arquivos dessa aula. E o código das importações é o mesmo da aula anterior.

 import os 
                 
 caminho = os.getcwd() 
 arquivo = caminho + r"\Pagina Hashitag.html" 
 navegador.get(arquivo) 

Ao abrir a página da hashtag no navegador, se clicarmos em um botão de algum curso, esse link será aberto em uma nova aba. Vamos copiar o XPATH desse botão para selecionarmos esse elemento.

 navegador.find_element(By.XPATH, '/html/body/section[2]/div/div[4]/figure/a/img').click() 

Vamos tentar preencher o campo Primeiro Nome do formulário da página do Power BI que acabou de abrir. Vamos selecionar esse elemento pelo name dele.

 <input type="textname="firtsnameplaceholder="Primeiro Nomerequired data="firstname"> == $0 

 # preenchendo o formulario 
                     
 navegador.find_element(By.ID, 'firstname').send_keys("Lira"
---------------------------------
 NoSuchElementException

Como podemos ver, o elemento não foi encontrado. Isso acontece porque por padrão o Selenium não muda de aba, ele continua olhando a aba original. Para resolver isso, antes de preencher o formulário precisamos mudar para a nova aba.

 aba_original = navegador.window_handles[0
 nova_aba = navegador.window_handles[1
 navegador.switch_to.window(nova_aba) 

.window_handles - Lista que tem todas as janelas abertas dentro do navegador que o Selenium está controlando. Os primeiros índices dessa lista correspondem às primeiras janelas abertas por ordem de abertura, ou seja, a primeira janela aberta é a de índice 0 (zero), e assim sucessivamente.

Como mudamos para a nova aba, agora conseguiremos preencher o formulário da página do Power BI.

 navegador.find_element(By.ID, 'firstname').send_keys("Lira"
 navegador.find_element(By.ID, 'email').send_keys("lira@lira.com"

E se quisermos mudar de volta para a aba original e clicar no botão Excel daquela página?

 navegador.switch_to.window(aba_original) 
 navegador.find_element(By.XPATH, '/html/body/section[2]/div/div[4]/figure/a/img').click() 

Funcionou! Agora podemos ver que estamos trabalhando com 3 abas diferentes dentro da nossa estrutura.

Se você estiver na dúvida em relação à ordem das suas abas, você pode fazer o seguinte:

 # ver os titulos de todas as abas 
 for aba in navegador.window_handles: 
     navegador.switch_to.window(aba) 
     print(navegador.title) 
_____________________________________________
 Todos os cursos Hashtag Treinamentos
 Curso de Power BI Avançado, Completo e Com Certificado!
 Curso de Exel Online Avançado, Completo e Com Certificado!

Com isso, vemos que a ordem é:
1ª Aba – Todos os Cursos (Aba Original) – Índice 0 (zero) da lista
2ª Aba – Curso de Power BI – Índice 1 da lista
3ª Aba – Curso de Excel – Índice 2 da lista

E se abrirmos um botão de algum curso em uma nova janela?

Apesar de ser uma nova janela, para o Selenium não vai mudar porque ele vai enxergar da mesma forma, como uma nova aba. É uma aba que está separada, mas isso não vai fazer diferença na forma como o Selenium irá enxergá-la.

Assim, a página do Curso de SQL será a 4ª aba, com índice 3 na lista

 abas = navegador.window_handles 
 print(len(abas)) 
_________________
 4 

E se quisermos preencher o formulário na página do SQL, como faremos?

 aba_sql = navegador.window_handles[3
 navegador.switch_to.window(aba_sql) 

 navegador.find_element(By.ID, 'firstname').send_keys("LiraSQL"
 navegador.find_element(By.ID, 'email').send_keys("sql@lira.com"

 <input type="textid="firtsname" name="firtsnameplaceholder="Primeiro Nomerequired data="firstname"> == $0 

 <input type="textid="email" name="emailplaceholder="Seu melhor e-mailrequired data="email"> == $0 

E como eu faço para fechar uma aba específica?

 # fechar a aba atualmente selecionada 
 navegador.close() 

E se eu quisesse fechar todas as abas ao mesmo tempo?

 # fechar todas as abas (navegador inteiro) 
 navegador.quit() 

– Como esperar uma informação carregar na tela

Nessa aula, vamos aprender a esperar um elemento aparecer dentro da nossa página usando o Selenium. Porque pode acontecer de um site carregar, mas algumas partes ainda não terem carregado. Normalmente, essas partes são carregadas por meio do Javascript alguns segundos depois da página ter sido carregada.
Como estamos trabalhando com o Selenium, e o padrão dele é somente esperar a página carregar, iremos utilizar alguns métodos para esperar também o carregamento de outros elementos.
Os métodos são:
1. WebDriverWait + ExpectedConditions (EC)
• Esse método é nativo do Selenium e espera até determinada condição acontecer por um determinado tempo.
• Menos linhas de códigos.
• Pode acontecer alguns bugs.
2. Loop de Espera
• Criação de uma espera “manual”.
• Nunca abandona.

O exemplo que faremos é dentro do site da hashtag. Se você esperar mais ou menos 7 segundos, um pop-up será aberto, como podemos ver na imagem abaixo.

 # criar o navegador 
 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
                       
 servico = Service(ChromeDriverManager().install()) 
 navegador = webdriver.Chrome(service=servico) 

 navegador.get("https://www.hashtagtreinamentos.com/"

Porém, esse pop-up não aparece na hora que você entra na página. E se quisermos que o nosso código em python feche esse pop-up? Então vamos na página clicar com o botão direito do mouse, selecionar inspecionar, clicar na seta e selecionar o X do pop-up.

 <i class="eicon-close"> 
     ::before == $0 
 </i> 

 navegador.get("https://www.hashtagtreinamentos.com/"
 navegador.find_element(By.CLASS_NAME, 'eicon-close').click() 

Como rodamos o código que entra no site da hashtag e o código que clica no “X” do pop-up ao mesmo tempo, não deu tempo de o pop-up aparecer, e por isso apareceu uma mensagem de erro de que o elemento que tentamos selecionar e clicar não foi encontrado.

Como resolver isso então?
• Solução 1

 import time 
                 
 navegador.get("https://www.hashtagtreinamentos.com/"
 time.sleep(15
 navegador.find_element(By.CLASS_NAME, 'eicon-close').click() 
 print("Fechou"
___________________
 Fechou 

• Espera 15 segundos após entrar no site da hashtag, e depois clica no elemento. Funciona, mas se o elemento demorar menos do que 15 segundos para aparecer, você estará atrasando a velocidade do seu código.

• Solução 2

 # EC WebDriverWait 
 from selenium.webdriver.common.by import By 
 from selenium.webdriver.support.ui import WebDriverWait 
 from selenium.webdriver.support import expected_conditions as EC 
                   
 navegador.get("https://www.hashtagtreinamentos.com/"
             
 elemento = WebDriverWait(navegador, 30).until(EC.presence_of_element_located((By.CLASS_NAME, 'eicon-close')))
 time.sleep(1) # garantia 
 elemento.click() 
 print("Fechou"
___________________
 Fechou 

• A condição é a que o elemento que estamos procurando, apareça na página. E então, passamos para o EC (Expected Conditions) uma tupla com o método de seleção, que é pelo nome da classe.
• O time.sleep(1) espera 1 segundo antes de clicar para dar tempo de o elemento carregar por completo na página.
• O WebDriverWait possui 2 parâmetros: o seu navegador e o tempo máximo para a espera do elemento. Depois é passado o método .until(), que literalmente significa até. Ou seja, o navegador vai esperar no máximo 30 segundos até que uma condição aconteça.

• Solução 3

 # loop 
 navegador.get("https://www.hashtagtreinamentos.com/"
            
 while len(navegador.find_elements(By.CLASS_NAME, 'eicon-close')) == 0
     time.sleep(1

 time.sleep(1) # garantia 
 navegador.find_element(By.CLASS_NAME, 'eicon-close').click() 

 print("Fechou"
___________________
 Fechou 

• Como vimos nas aulas anteriores, o .find_elements() nos dá como resposta, uma lista de elementos. O while ficará testando se o tamanho da lista é igual a zero, ou seja, se o nosso elemento não apareceu. Se o elemento ainda não tiver aparecido, espera 1 segundo.
• Depois que o elemento tiver aparecido na página, espera 1 segundo para dar tempo de o elemento ser completamente carregado.

Esses foram os 3 métodos para esperar um elemento carregar na página.

– Printscreen com Selenium

Nessa aula, vamos aprender como tirar um print da sua tela com o Selenium. Existem 2 formas de print:
• Print da tela inteira
• Print de uma parte da tela
O print de uma parte da tela é na verdade um print da tela inteira, que depois é cortado em um tamanho menor, de acordo com as posições dos elementos que você quer tirar o print.
Lembrando que utilizaremos o mesmo código de importação que verifica a versão do ChromeDriver e abre o nosso navegador, e o mesmo código que abre a página da hashtag.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install()) 
 navegador = webdriver.Chrome(service=servico) 

• Importações e configuração do navegador

 import os 
                 
 caminho = os.getcwd() 
 arquivo = caminho + r"\Pagina Hashtag.html" 
 navegador.get(arquivo) 

• Abrindo página da hashtag no navegador

O print sempre vai ser do que está aparecendo no seu navegador. Por exemplo, se você rolar a barra de rolagem para baixo, o seu print será diferente. Se você maximizar o seu navegador, o seu print também será diferente do anterior.
A forma de tirar o print é:

 navegador.save_screenshot("print.png"
__________________
 True 

print.png - Nome do arquivo, com a extensão de imagem. Nesse caso, será salvo como arquivo png. Se você quiser salvar como arquivo jpg, é só escrever: nome_do_arquivo.jpg.
Esse arquivo será salvo na mesma pasta do seu código. Caso você queira salvar em um
local diferente, é só passar o caminho completo do local junto ao nome do arquivo.

Para tirar print de uma parte da sua tela, como falado anteriormente, vamos cortar a imagem. Para isso, vamos precisar usar uma ferramenta de edição de imagem: OpenCV ou Pillow. Nessa aula iremos utilizar o Pillow.

 from PIL import Image 
                                  
 imagem = Image.open("print.png"
                                  
 imagem = imagem.crop() 
                                  
 imagem.save("print_pedaco.png"

• Importa Image da biblioteca PIL (Pillow).
• Abre o print que tiramos do navegador e armazena na variável imagem.
• Método .crop() que corta a imagem de acordo com os parâmetros passados. Nesse caso, o print será cortado e salvo na variável imagem.
• Salva a imagem no mesmo local do seu código com o nome “print_pedaço.png”.

Como faremos esse corte? E quais são os parâmetros do método .crop()? Para cortar uma imagem usando o .crop(), temos que passar uma tupla como parâmetro. Essa tupla deverá conter a posição de 2 pontos, que veremos na próxima página (círculos laranjas).

Podemos ver o ponto (0, 0) na imagem e ver que conforme avançamos para a direita, o nosso valor de x cresce, e conforme avançamos para baixo, o nosso valor de y cresce. Os círculos laranjas são os pontos que devemos passar para o método .crop() como parâmetro.
Assim fica .crop((x_inicial, y_inicial, x_final, y_final)). E para descobrir o valor do x_final e do y_final, faremos:

x_final = x_inicial + largura
y_final = y_inicial + altura

Vamos escolher um elemento no navegador para que possamos tirar um print desse elemento. Por exemplo, se quisermos tirar um print da barra de navegação? Vamos clicar com o botão direito do mouse, e selecionar inspecionar. Depois vamos clicar nos três pontinhos da direita, e em Dock side, selecionar a 3ª opção.
Pronto, modificamos a posição da barra porque assim fica mais fácil de visualizarmos o elemento que queremos.

 <header id="header" role="banner" class> == $0 

Vamos selecionar o elemento pelo seu ID e pegar a sua posição. Essa posição se refere ao (x_inicial, y_inicial), então sabemos que o x_inicial desse elemento é 0 (zero) e o y_inicial desse elemento também é 0 (zero).

 elemento = navegador,find_element(By.ID, 'header'
 posicao = elemento.location 
 print(posicao) 
____________________
 {'x': 0, 'y': 0} 

Isso faz sentido, já que podemos ver que o nosso elemento está começando no ponto (0, 0), que está indicado pelo círculo preto. Vamos pegar também o tamanho desse elemento.

 elemento = navegador,find_element(By.ID, 'header'
 tamanho = elemento.size 
 print(tamanho) 
____________________
 {'height': 146, 'width': 1019} 

Então temos 2 dicionários, o dicionário posição (com chaves x e y) e o dicionário tamanho (com chaves height e width).

Agora vamos descobrir quais são os valores que teremos que passar para o .crop() como parâmetro e como ficará a imagem cortada.

 from PIL import Image 
                                  
 imagem = Image.open("print.png"
                    
 elemento = navegador,find_element(By.ID, 'header'
 posicao = elemento.location 
 tamanho = elemento.size 
             
 x_inicial = posicao["x"
 y_inicial = posicao["y"
 x_final = x_inicial + tamanho["width"
 y_final = y_inicial + tamanho["height"
          
 imagem = imagem.crop((x_inicial, y_inicial, x_final, y_final)) 
 imagem.save("print_pedaco.png"

x_final = x_inicial + largura
y_final = y_inicial + altura
Tupla (x_inicial, y_incial, x_final, y_final)

Pronto! Vamos verificar como ficou o print e o print do pedaço.

Podemos ver na página anterior que o print do pedaço não ficou totalmente certo, pois cortou algumas partes da barra de navegação. Isso pode acontecer com você também, caso a escala do seu monitor esteja diferente de 100%.

Como essa é uma alteração de cálculo que faz tudo que está aparecendo na minha tela ficar com 125% de tamanho, os valores que “printamos” de tamanho e posição não condizem com o que está aparecendo na minha tela. Para resolver isso, existem 2 formas:
Colocar o valor da escala em 100% ou multiplicar os valores de tamanho e posição pelo valor da escala, que no meu caso é 125% (1.25).
Então multiplicaremos a escala (1.25, no meu caso) pelos valores: x_inicial, y_inicial, altura e largura, que foram os valores que pegamos do elemento. Fazendo essa alteração, o código fica:

 from PIL import Image 
                                  
 imagem = Image.open("print.png"
                    
 elemento = navegador,find_element(By.ID, 'header'
 posicao = elemento.location 
 tamanho = elemento.size 
             
 x_inicial = posicao["x"]*1.25 
 y_inicial = posicao["y"]*1.25 
 x_final = x_inicial + tamanho["width"]*1.25 
 y_final = y_inicial + tamanho["height"]*1.25 
          
 imagem = imagem.crop((x_inicial, y_inicial, x_final, y_final)) 
 imagem.save("print_pedaco.png"

Agora vamos verificar os prints novamente, após as alterações.

Podemos verificar que agora deu certo! Inclusive na imagem abaixo do print do pedaço, mostra a seleção do elemento ao clicar em inspecionar, e essa seleção mostra exatamente que o print do pedaço da tela está correto.

– Gerenciando a tela do Navegador

Agora nessa aula, vamos aprender a gerenciar a tela do nosso navegador: maximizar, minimizar e rodar o navegador de forma oculta (que chamamos de modo headless). O código padrão inicial de importações e abrir a página da hashtag é o mesmo.
Quando abrimos o nosso navegador, podemos perceber que ele nunca está maximizado. Como podemos maximizá-lo através do código? Para maximizar o navegador é só rodar o código abaixo:

 navegador.maximize_window() 

E como faço para minimizar o navegador?

 navegador.minimize_window() 

Lembrando que o minimizar não é clicar no botão de minimizar, mas sim o navegador voltar ao tamanho original de quando o abrimos. Mas caso você queira que o seu navegador rode de forma oculta, então você gostaria de utilizar o modo headless.

O que é o modo headless? O significado literal é “sem cabeça”, mas é um modo no qual o seu navegador executa o seu código de forma escondida, sem abrir o seu navegador. Para utilizar o modo headless, precisamos fazer algumas configurações.

 options = webdriver.ChromeOptions() 
 options.add_argument('--headless'
 novo_nav = webdriver.Chrome(service=servico, options=options) 
                         
 novo_nav.get("https://hashtagtreinamentos.com"
 print(novo_nav.title) 
__________________ 
 Hashtag Treinamentos | Torne-se uma referência em qualquer empresa 

• O .ChromeOptions() é uma classe no Selenium que permite manipular várias propriedades do ChromeDriver.
• Adiciona um argumento de linha de comando, que nesse caso é o ‘--headless’ (que deixa o seu navegador escondido). Esse argumento é aplicado no seu navegador.
• O argumento de palavra-chave options recebe a variável options, que indicará como o navegador será aberto.

Perceba que ele imprimiu o título do site da hashtag, mas não abriu nenhum navegador
Você pode pesquisar no google os argumentos que você pode adicionar além de “--headless”. Por exemplo, você pode pesquisar:
“selenium python como abrir o navegador com extensões desabilitadas”, e provavelmente você achará o “--disable-extensions”

 D I C A 
Construa todas as suas automações sem o modo headless. Porque você poderá ver o que está funcionando no seu código e o que não está, e com isso você poderá fazer os ajustes necessários. Depois disso, você poderá colocar o modo headless. Isso porque alguns sites se comportam de forma diferente no modo headless, e isso poderá impactar o funcionamento do seu código.

– Carregando um navegador com Cookies e Logins

Agora vamos ver como resolver um problema para quem quer automatizar envio de mensagens no WhatsApp ou algum serviço que você já tenha que estar logado para utilizá-lo. Para isso, precisaremos criar um perfil do Google Chrome por meio do nosso código. Assim que este perfil for criado, você poderá utilizá-lo para fazer login nas plataformas que você quiser, pois uma vez que você esteja logado nessas plataformas através desse perfil, você não precisará logar novamente nessas plataformas.
Para configurar o navegador, precisaremos do .ChromeOptions() que vimos na aula passada, que nos permite adicionar argumentos que serão aplicados no nosso navegador.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install())
 options = webdriver.ChromeOptions()
 options.add_argument(r"user-data-dir=C:\Users\Felipe\AppData\Local\Google\Chrome\User Data\Defalt")
 navegador = webdriver.Chrome(service=servico, options=options) 

O argumento “user-data-dir” diz qual perfil do Chrome ele irá carregar junto ao caminho do local onde está armazenado este perfil. No meu caso, o caminho é o que está na imagem. Para saber o caminho do seu perfil é só digitar no Chrome sem aspas “chrome://version”, e na página que abrir você vai copiar o caminho que está ao lado de “Caminho de perfil”.

Vamos entrar agora no local que copiamos na página anterior.
• Repare que na pasta User Data, temos a pasta Default, e se você tiver outros perfis do Chrome já configurados, você verá pastas com um nome padrão, por exemplo “Profile1”, “Profile2”, “Profile3”, dependendo de quantos perfis já configurados você possuir.

Na pasta Default, temos todas as informações desse usuário como Contas, Cache, Preenchimento Automático, etc.

No caminho que copiamos no nosso código, nós temos o caminho da pasta User Data, mas esse caminho estava entrando dentro da pasta Default. Não queremos entrar na pasta Default, e no lugar de “Default” vamos escrever “Profile Selenium”. O “Profile Selenium” é um perfil que ainda não existe. Quando rodarmos esse código pela primeira vez, esse perfil será criado.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install())
 options = webdriver.ChromeOptions()
 options.add_argument(r"user-data-dir=C:\Users\Felipe\AppData\Local\Google\Chrome\User Data\Profile Selenium")
 navegador = webdriver.Chrome(service=servico, options=options) 

 navegador.get("https://web.whatsapp.com"

• Podemos ver que agora o perfil “Profile Selenium” foi criado, e dentro do “Profile Selenium” estarão todas as informações que esse perfil for armazenando. Agora você terá que fazer login no seu WhatsApp, nas plataformas e ferramentas que você quiser.

Vamos executar todo o código, inclusive o código para ir para a página do WhatsApp. Vamos fazer login na nossa conta de WhatsApp também.
Pronto! Agora que conectamos à nossa conta de WhatsApp, vamos fechar o navegador e executar a primeira parte do nosso código novamente.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install())
 options = webdriver.ChromeOptions()
 options.add_argument(r"user-data-dir=C:\Users\Felipe\AppData\Local\Google\Chrome\User Data\Profile Selenium")
 navegador = webdriver.Chrome(service=servico, options=options) 

• Podemos ver que o WhatsApp já está no nosso histórico de navegação

Vamos fechar o nosso navegador novamente. Agora vamos executar o nosso código mais uma vez, mas dessa vez vamos executar o código todo.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
               
 servico = Service(ChromeDriverManager().install())
 options = webdriver.ChromeOptions()
 options.add_argument(r"user-data-dir=C:\Users\Felipe\AppData\Local\Google\Chrome\User Data\Profile Selenium")
 navegador = webdriver.Chrome(service=servico, options=options) 

 navegador.get("https://web.whatsapp.com"

Pronto! Nosso navegador conectou à nossa conta de WhatsApp, sem que precisássemos fazer o login novamente. A partir de agora nosso login ao WhatsApp está automatizado.
Quando carregamos um perfil, o nosso navegador demora um pouco mais para responder os primeiros comandos, porque todas as informações do perfil estão sendo carregadas e isso faz com que o navegador fique um pouco mais “pesado”, portanto não se preocupe
porque isso é normal.

– Executando Scripts em Javascript pelo Selenium (Scroll na tela)

Agora vamos aprender a usar o Selenium para executar comandos em Javascript dentro do nosso navegador. Mas por quê? Porque a estrutura de um site é feita em HTML e CSS, e a parte dinâmica dos sites é feita normalmente em Javascript. Rodar scripts em Javascript dentro do Selenium é importante porque nos permite fazer muito mais coisas. Por exemplo, suponhamos que a Hashtag pesquise “python” dentro do youtube e apareça como resultado uma lista de vídeos, e a Hashtag queira fazer propaganda em todos os vídeos de python do youtube. Quando arrastamos para baixo a barra de rolagem, percebemos que os vídeos que aparecem na lista não são carregados todos de uma vez, são carregados aos poucos conforme vamos descendo a barra de rolagem.
Se a Hashtag precisar pegar 50 vídeos, teremos que dar um scroll na página primeiro, depois esperar os vídeos serem carregados e aí sim, pegar o link dos vídeos. Então, nesse exemplo executaremos script para fazer exatamente isso.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
 from selenium.webdriver.common.keys import Keys 
 import time

 servico = Service(ChromeDriverManager().install())
 navegador = webdriver.Chrome(service=servico)

 navegador.get("https://www.youtube.com")
 time.sleep(2)

Agora, vamos pesquisar “python” dentro do youtube. Para isso, vamos inspecionar a barra de busca do youtube, e vamos tentar selecionála e mandar a palavra “python” e a tecla Enter para fazer a busca.

 lista_inputs = navegador.find_elements(By.TAG_NAME, 'input'
 for elemento in lista_inputs: 
     if elemento.get_attribute("id") == "search"
         elemento.send_keys("python"
         elemento.send_keys("keys.ENTER") 
         break 
 time.sleep(5) 

Nesse código, estamos selecionando todos os elementos que possuem a tag input (mesma tag da barra de pesquisa) e os armazenando em uma lista. Percorremos os elementos dessa lista, testando se algum deles possui o atributo “id” igual a search. Em caso afirmativo, ele manda a palavra “python” para esse elemento, envia a tecla Enter, e depois sai do loop.

Agora, vamos extrair o link dos vídeos

• Podemos ver que o link que está dentro do elemento da imagem <img> é o endereço da imagem, e não o endereço do vídeo que estamos procurando. Quando isso acontecer, devemos procurar algum elemento próximo que tenha o atributo href.

Podemos ver que no elemento que achamos, seu id é “thumbnail”. Geralmente, o atributo id é único, mas nesse caso, todos os outros vídeos também possuem id igual a “thumbnail”. Então, em vez de pegarmos apenas um elemento, vamos pegar uma lista de elementos que possuem o mesmo id.

 lista_videos = navegador.find_elements(By.ID, 'thumbnail'
 for video in lista_videos: 
     print(video.get_attribute("href")) 

Podemos ver que na página anterior, o nosso código “printou” vários links. E se quisermos pegar muito mais links? Para isso, antes de executar o código que pega os links dos vídeos, vamos ter que dar scroll na página. E como fazer para dar scroll na página?

Para dar scroll na página, teremos que executar um comando em Javascript. E para isso, devemos fazer: navegador.execute_script(“”). E dentro dos parênteses e entre aspas devemos passar o comando em Javascript que queremos executar.

Agora, vamos clicar em inspecionar na página e clicar em Console.

 >window.skroll(0, 500) 

Esse comando em Javascript, window.scroll(x, y); Dá scroll na página para a posição que passarmos dentro dos parênteses. Onde X se refere à posição do scroll horizontal e
Y se refere à posição do scroll vertical. Nesse caso, o nosso comando dá scroll vertical para a posição 500.

E o que fazer para a nossa página sempre ficar arrastando para baixo? Teremos que colocar o nosso comando dentro de um loop e atualizarmos a posição que passaremos como parâmetro dentro do comando em Javascript.

 #dar scroll na tela
 import time
                  
 for i in range(15):
     qtde_scroll = i * 4000
     navegador.execute_script(f'window.scroll(0, {qtde_scroll})')
     time.sleep(2)
                 
 lista_videos = navegador.find_elements(By.ID, 'thumbnail')
               
 for video in lista_videos:
     print(video.get_attribute("href"))

• O time.sleep(2) é muito importante, porque espera o carregamento dos vídeos na página antes de dar o próximo scroll. Dessa forma, conseguimos pegar muito mais vídeos.

– Trabalhando com iFrames

Nessa aula, vamos trabalhar com IFrames dentro do Selenium. Um IFrame nada mais é que uma página dentro de outra página. É quando você quer pegar uma informação e colocar dentro da página, e essa informação está vindo de outra página.
Por que falar de IFrames? Porque às vezes você fará tudo certo no Selenium, mas de jeito nenhum seu código funcionará, porque o elemento não será encontrado. Se isso acontecer, talvez esse elemento esteja dentro de um IFrame.

Nesse nosso caso, o link que acessamos é um painel com jogos do dia, onde podemos ver uma tabela, que é um relatório do Power BI. O que queremos é acessar as informações dessa tabela. E se quisermos acessar “Pontos por Jogo Mandante” da 1ª linha da tabela, cujo valor é 2,20, como faremos?

Abaixo está o nosso código com as importações e configura configurações para acessar o site com o Selenium.

 from selenium import webdriver 
 from selenium.webdriver.chrome.service import Service 
 from webdriver_manager.chrome import ChromeDriverManager 
 from selenium.webdriver.common.by import By 
 from selenium.webdriver.common.keys import Keys 
 import time

 servico = Service(ChromeDriverManager().install())
 navegador = webdriver.Chrome(service=servico)

 link = "https://pbdatatrader.com.br/jogosdodia"

 navegador.get(link)
 time.sleep(7)

Como faríamos normalmente para selecionar o elemento no qual estamos interessados? Iríamos clicar em inspecionar a página, com a seta selecionaríamos o elemento, e copiaríamos o XPATH dele.

Agora, vamos tentar selecioná-lo pelo XPATH.

 texto = navegador.find_element(By.XPATH, '''//*[@id="pvExplorationHost"]/div/div/exploration/div/explore-canvas/div/div[2]/div/div[2]/div[2]/visual-container-repeat/visual-container[19]/transform/div/div[2]/div/visual-modern/div/div/div[2]/div[1]/div[4]/div/div[1]/div[8]''').text
 print(texto)
-----------------------
 NoSuchElementException

A mensagem de erro diz que o elemento não existe. Mas como? Se inspecionarmos o relatório do Power BI e clicarmos no elemento que estamos interessados, e depois subirmos buscando entender a hierarquia dos elementos na página, descobriremos que esse elemento está dentro de 2 IFrames.

O Selenium não consegue ler dentro de um IFrame, precisamos avisar ao Selenium para parar de olhar para a página principal e olhar para o IFrame. Já no nosso caso, teremos que falar para ele para olhar para o IFrame de fora, e depois olhar para o IFrame de dentro, e aí sim tentar selecionar o nosso elemento.

Como explicado na página anterior, entraremos nos 2 IFrames. Vamos selecionar o IFrame pelo nome da tag <iframe>. Importante lembrar que quando você entra em um IFrame, você não consegue mais pegar informações da página principal, a não ser que você volte para a página principal novamente.

 iframe = navegador.find_element(By.TAG_NAME, 'iframe')
 navegador.switch_to.frame(iframe)
         
 iframe = navegador.find_element(By.TAG_NAME, 'iframe')
 navegador.switch_to.frame(iframe)

 valor_xpath = '//*[@id="pvExplorationHost"]/div/div/exploration/div/explore-canvas/div/div[2]/div/div[2]/div[2]/visual-container-repeat/visual-container[19]/transform/div/div[2]/div/visual-modern/div/div/div[2]/div[1]/div[4]/div/div[1]/div[8]'
 texto = navegador.find_element(By.XPATH, valor_xpath).text
 print(texto)

Pronto! Agora conseguimos obter a informação do elemento que estávamos interessados. E se quisermos voltar à página principal?

 navegador.switch_to.defalt_content() 

Com esse código, você voltará à página principal! Com isso, você conseguirá selecionar os elementos da página principal novamente.

Nenhum comentário:

Postar um comentário