Reputation: 11
I'm trying to write a Python script using selenium's webdriver, to automate the task of uploading invoices to the federal online ledger.
I know this is a common question, but after reading many questions in SO and trying their answers, I couldn't find a solution.
This is the html code I want to select and click on:
<input id="idcontribuyente" type="hidden" name="idContribuyente">
<input class="btn_empresa ui-button ui-widget ui-state-default ui-corner-all" type="button" style= "width:100%" onclick="document.getElementById('idcontribuyente').value='0';document.seleccionaEmpresaForm.submit();" role="button">
These are the main things I've tried so far:
(first with the WebDriverWait() and then with time.sleep(20), just in case there was an error there)
#1
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, "btn_empresa")))
empresa_btn = driver.find_element_by_class_name('btn_empresa')
empresa_btn.click()
#2
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all')))
empresa_btn = driver.find_element_by_css_selector('.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all')
empresa_btn.click()
#3
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, "//input[@type='button']")))
empresa_btn = driver.find_element_by_css_selector("//input[@type='button']")
empresa_btn.click()
#4
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, "//input[@type='button']")))
empresa_btn = driver.find_element_by_xpath("//input[@type='button']")
empresa_btn.click()
#5
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//td[@align="center"]/input')))
empresa_btn = driver.find_element_by_css_selector('//td[@align="center"]/input')
empresa_btn.click()
#6
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH,"//input[@class='btn_empresa ui-button ui-widget ui-state-default ui-corner-all']")))
empresa_btn = driver.find_element_by_xpath("//input[@class='btn_empresa ui-button ui-widget ui-state-default ui-corner-all']")
empresa_btn.click()
The error when using time.sleep(20):
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: element_name
The error when using WebDriverWait():
selenium.common.exceptions.TimeoutException: Message:
I'm pretty new to this. What am I doing wrong?
many thanks in advance!
UPDATE - SOLUTION:
I found a way, I've used a Selenium IDE and exported the code to inspect it. Apparently it had to do with switching windows. This code works (although it may be more verbose than it needs to be):
vars = {}
vars["window_handles"] = driver.window_handles
# This line already worked before. It is for the previous page
driver.find_element_by_xpath("//div[@title='rcel']").click()
# Here it comes the way to select and click on the problematic button
def wait_for_window(timeout = 2):
time.sleep(round(timeout / 1000))
wh_now = driver.window_handles
wh_then = vars["window_handles"]
if len(wh_now) > len(wh_then):
return set(wh_now).difference(set(wh_then)).pop()
vars["win806"] = wait_for_window(2000)
driver.switch_to.window(vars["win806"])
driver.find_element(By.CSS_SELECTOR, ".btn_empresa").click()
This is how the actual webpage looked like: red triangle indicates the button I wanted to click on
Upvotes: 1
Views: 225
Reputation: 1
#emitir factura
emitirf_input =driver.find_element(By.ID, "bBtn1")
emitirf_input.send_keys(Keys.RETURN)
time.sleep(3)
driver.switch_to.window(driver.window_handles[1])
#cargo la pestaña nueva que se abre
driver.get("https://fe.afip.gob.ar/rcel/jsp/index_bis.jsp#")
#contribuyente
contri_input =driver.find_element(By.ID, "idcontribuyente")
contri_input =driver.find_element(By.CLASS_NAME, 'btn_empresa')
contri_input.send_keys(Keys.RETURN)
time.sleep(3)
Upvotes: -1
Reputation: 4212
First wait, then click:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all')))
empresa_btn = driver.find_element_by_css_selector('.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all').click()
Some of the steps you've tried were very close.
If the element you want to click is hidden, try using driver.execute_script
:
element = driver.find_element_by_css_selector("#idcontribuyente")
driver.execute_script("$(arguments[0]).click();", element)
Update 1, try to click the second input:
element = driver.find_element_by_css_selector(".btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all")
driver.execute_script("$(arguments[0]).click();", element)
Update 2, probably you have few similar css locators similar to above: try using:
tr:nth-of-type(4)>td>.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all
Update 3 Check if your button is located inside shadow DOM. If it is - none of the methods you tried will work. Check how to enable showing shadow DOM.
Update 4 As mentioned in the comment to your question, your second xpath was good. Try using it this way:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='btn_empresa ui-button ui-widget ui-state-default ui-corner-all']")))
empresa_btn = driver.find_element_by_xpath("//input[@class='btn_empresa ui-button ui-widget ui-state-default ui-corner-all']").click()
Upvotes: 1
Reputation: 3801
Maybe try...
driver.find_element_by_xpath("//input[@id='idcontribuyente']/following-sibling::input")
Since it is 2 input
tags next to each other, this finds the one by ID
first and takes the input
sibling directly after it. Not sure it will work since I can't access the URL, but give it a shot
Upvotes: 1