Reinaldo Chaves
Reinaldo Chaves

Reputation: 995

In selenium how to access warnings window for information not found?

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

Answers (4)

Tarun Lalwani
Tarun Lalwani

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

SIM
SIM

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

demouser123
demouser123

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

K. Thompson
K. Thompson

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()

Also see: http://selenium-python.readthedocs.io/api.html?highlight=send_keys#module-selenium.webdriver.common.action_chains

Upvotes: 1

Related Questions