Reputation: 995
In python 3 and selenium I have this program to enter codes in a website and store the information returned:
from selenium import webdriver
profile = webdriver.FirefoxProfile()
browser = webdriver.Firefox(profile)
# Site that is accessed
browser.get('https://www.fazenda.sp.gov.br/SigeoLei131/Paginas/ConsultaDespesaAno.aspx?orgao=')
# Select year 2018
browser.find_element_by_xpath('/html/body/form/div[3]/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr[1]/td[2]/select/option[1]').click()
# Enter the code 07022473000139
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_rblDoc_0"]').click()
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_txtCPF"]').send_keys('07022473000139')
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnPesquisar"]').click()
# Stores the information found
company = browser.find_element_by_xpath('/html/body/form/div[3]/table/tbody/tr[2]/td/table/tbody/tr[3]/td/div/table/tbody/tr[2]/td[1]').text
value = browser.find_element_by_xpath('/html/body/form/div[3]/table/tbody/tr[2]/td/table/tbody/tr[3]/td/div/table/tbody/tr[2]/td[2]').text
# Go back one screen to do another search
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnVoltar"]').click()
I have a list of codes to search the site in the field: "CNPJ/CPF/Inscrição genérica/UGE favorecida :"
In this list I have already discovered that some codes do not exist in the site database (I do not know how many do not exist). And when I type a code that does not exist (like '07022473000136') a window opens on the site with the message "Não existe Credor com o filtro informado" and I can only continue by pressing the OK button
I did not find this warning message in the site code, so I still do not know how to handle it
Please, would anyone know how to test whether or not the code exists in selenium? And if not, how do I press the OK button to continue?
-/-
Below is a new test, to look for various codes that are in a dataframe. This program worked:
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.support.select import Select
import pandas as pd
deputados_socios_empresas = pd.read_csv("resultados/empresas_deputados.csv",sep=',',encoding = 'utf-8', converters={'cnpj': lambda x: str(x), 'cpf': lambda x: str(x), 'documento': lambda x: str(x)})
profile = webdriver.FirefoxProfile()
browser = webdriver.Firefox(profile)
# Important command to pause, during loop
browser.implicitly_wait(10)
# Site that is accessed
browser.get('https://www.fazenda.sp.gov.br/SigeoLei131/Paginas/ConsultaDespesaAno.aspx?orgao=')
# List to store the data
pagamentos = []
for num, row in deputados_socios_empresas.iterrows():
# Variable with code to search
empresa = (row['cnpj']).strip()
# Search for each code in four years
for vez in [2015, 2016, 2017, 2018]:
ano = str(vez)
# Select year
Select(browser.find_element_by_name('ctl00$ContentPlaceHolder1$ddlAno')).select_by_visible_text(ano)
# Fill in the code to search
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_rblDoc_0"]').click()
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_txtCPF"]').send_keys(empresa)
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnPesquisar"]').click()
try:
found = True
alert = browser.switch_to.alert
alert.accept()
found = False
# Message shows that the code was not found that year
print("CNPJ " + empresa + " não encontrado no ano " + ano)
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnVoltar"]').click()
except NoAlertPresentException:
pass
if found:
results = browser.find_element_by_xpath("//table[@id='ctl00_ContentPlaceHolder1_gdvCredor']//tr[2]")
cia = results.find_element_by_xpath("td[1]").text
valor = results.find_element_by_xpath("td[2]").text
#Message shows that the code was found that year
print("CNPJ " + empresa + " encontrado no ano " + ano)
# Fills dictionary with found data
dicionario = {"cnpj": empresa,
"ano": ano,
"empresa": cia,
"valor": valor,
}
pagamentos.append(dicionario)
# Go back one screen to do another search
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnVoltar"]').click()
# Create the dataframe
df_pagamentos = pd.DataFrame(pagamentos)
Upvotes: 0
Views: 517
Reputation: 146610
First of all you should not be using such bad xpaths. I think you copied them from auto generate xpath option which is not good.
Next what you need is to check the presence of the alert in case of failure. Below is the updated code that should work for you
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.support.select import Select
profile = webdriver.FirefoxProfile()
browser = webdriver.Firefox(profile)
# Site that is accessed
browser.get('https://www.fazenda.sp.gov.br/SigeoLei131/Paginas/ConsultaDespesaAno.aspx?orgao=')
# Select year 2018
Select(browser.find_element_by_name('ctl00$ContentPlaceHolder1$ddlAno')).select_by_visible_text("2018")
# Enter the code 07022473000139
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_rblDoc_0"]').click()
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_txtCPF"]').send_keys('07022473000136')
# browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_txtCPF"]').send_keys('07022473000139')
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnPesquisar"]').click()
try:
found = True
alert = browser.switch_to.alert
alert.accept()
found = False
print("no data was found")
except NoAlertPresentException:
pass
if found:
results = browser.find_element_by_xpath("//table[@id='ctl00_ContentPlaceHolder1_gdvCredor']//tr[2]")
company = results.find_element_by_xpath("td[1]").text
value = results.find_element_by_xpath("td[2]").text
print(company, value)
# Go back one screen to do another search
browser.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnVoltar"]').click()
Upvotes: 1
Reputation: 22440
To do the operation in a slightly organized manner, you can try the below way. Your defined xpaths
are error prone. However, driver.switch_to_alert().accept()
is not a big issue to deal with, what does important is where to place it. I've tried with three searches, of which the one in the middle should encounters the issue and handles it in the proper way.
This is what i would do in this situation:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import UnexpectedAlertPresentException
url = 'https://www.fazenda.sp.gov.br/SigeoLei131/Paginas/ConsultaDespesaAno.aspx?orgao='
def get_values(driver,link):
for keyword in ["07022473000139","07022473000136","07022473000139"]:
driver.get(link)
wait = WebDriverWait(driver, 10)
item = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "select[name='ctl00$ContentPlaceHolder1$ddlAno']")))
select = Select(item)
select.select_by_visible_text("2018")
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'#ctl00_ContentPlaceHolder1_rblDoc_0'))).click()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'#ctl00_ContentPlaceHolder1_txtCPF'))).send_keys(keyword)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'#ctl00_ContentPlaceHolder1_btnPesquisar'))).click()
try:
company = wait.until(EC.visibility_of_element_located((By.XPATH, "//tr[contains(.//th,'Credor')]/following::a"))).text
value = wait.until(EC.visibility_of_element_located((By.XPATH, "//tr[contains(.//th[2],'Valor')]/following::td[2]"))).text
print(f'{company}\n{value}\n')
except UnexpectedAlertPresentException:
driver.switch_to_alert().accept()
print("Nothing found"+"\n")
if __name__ == '__main__':
driver = webdriver.Chrome()
try:
get_values(driver,url)
finally:
driver.quit()
Upvotes: 1
Reputation: 4264
You need to add this import statement
from selenium.common.exceptions import UnexpectedAlertPresentException
and after these lines
driver.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_rblDoc_0"]').click()
driver.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_txtCPF"]').send_keys('07022473000136')
driver.find_element_by_xpath('//*[@id="ctl00_ContentPlaceHolder1_btnPesquisar"]').click()
add
try:
driver.switch_to.alert.accept()
except UnexpectedAlertPresentException:
print('passing')
which will accept the alert present in the browser.
Edit 1: Tarun's answer is a much better implementation. Please use it as an answer.
Upvotes: 1
Reputation: 25
You can use action chains to send keystrokes to the browser and not a particular page element.
actions = ActionChains(driver)
actions.send_keys(Keys.ENTER)
actions.perform()
Upvotes: 1