我正在尝试使用 selenium 的 webdriver 编写一个 Python 脚本,以自动执行将发票上传到联邦在线分类帐的任务。
我知道这是一个常见问题,但是在阅读了SO中的许多问题并尝试了他们的答案后,我找不到解决方案。
这是我要选择并点击的html代码:
<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">
这些是我迄今为止尝试过的主要内容:
(首先使用 WebDriverWait(),然后使用 time.sleep(20),以防万一出现错误)
#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()
使用time.sleep(20)时的错误:
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: element_name
使用WebDriverWait()时的错误:
selenium.common.exceptions.TimeoutException: Message:
我对此还很陌生。我做错了什么?
提前非常感谢!
更新 - 解决方案:
我找到了一种方法,我使用了 Selenium IDE 并导出了代码来检查它。显然这与切换窗口有关。这段代码有效(尽管它可能比需要的更冗长):
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()
也许尝试一下...
driver.find_element_by_xpath("//input[@id='idcontribuyente']/following-sibling::input")
由于它是 2 个彼此相邻的
input
标签,因此首先找到 ID
所在的标签,并直接在其后找到 input
同级。 不确定它是否有效,因为我无法访问该 URL,但请尝试一下
先等待,然后点击:
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()
您尝试过的一些步骤非常接近。
如果您要单击的元素被隐藏,请尝试使用
driver.execute_script
:
element = driver.find_element_by_css_selector("#idcontribuyente")
driver.execute_script("$(arguments[0]).click();", element)
更新1,尝试点击第二个输入:
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)
更新2,可能你有几个类似上面的CSS定位器: 尝试使用:
tr:nth-of-type(4)>td>.btn_empresa.ui-button.ui-widget.ui-state-default.ui-corner-all
更新3 检查您的按钮是否位于 Shadow DOM 内部。如果是 - 您尝试过的方法都不起作用。检查如何启用显示 Shadow DOM。
更新4 正如对您的问题的评论中提到的,您的第二个 xpath 很好。 尝试这样使用它:
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()
#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)