【问题标题】:Selenium not able to locate element that actually existsSelenium 无法定位实际存在的元素
【发布时间】:2019-07-17 22:37:08
【问题描述】:

我正在自动化一个无聊的数据输入任务,所以我创建了一个程序,它基本上使用 selenium 为我点击和输入。它运行得很好!除了当它到达我需要单击的这个特定的“编辑详细信息...”元素时,无论我尝试什么方法,selenium 都无法找到该元素。

我尝试使用试图访问 ID 的 CSS 选择器无济于事。我还尝试使用 XPATH,并尝试通过给它一个带有按钮文本的“包含”语句来更具体。作为最后的手段,我使用 selenium IDE 查看当我物理单击按钮时它注册的定位器,它使用了与我在代码中声明的完全相同的 ID。我完全不知道如何解决这个问题。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import *

import pyautogui as py
import time, sys, os, traceback


#Launching Browser
browser = webdriver.Ie()
wait = WebDriverWait(browser, 15) #Waiting


#Laziness Functions
def clickCheck(Method, Locator, elemName):
    wait.until(EC.element_to_be_clickable((Method, Locator)))
    print(elemName + ' Clickable')




#Commence main function
try:

    #Do alot of Clicks and Stuff until it reaches "Edit Details..." element

    """THIS IS WHERE THE PROBLEM LIES"""
    time.sleep(3)
    clickCheck(By.CSS_SELECTOR, 'td[id="DSCEditObjectSummary"]', "Edit Details")
    elemEdit = browser.find_element_by_css_selector('td[id="DSCEditObjectSummary"]')
    elemEdit.click()




#FAILSAFES

except:
    print('Unknown error has Occured')
    exc_info = sys.exc_info()
    traceback.print_exception(*exc_info)
    del exc_info

finally: #Executes at the end and closes all processes
    print('Ending Program')
    browser.quit()
    os.system("taskkill /f /im IEDriverServer.exe")
    sys.exit()

raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to find element with css selector == [id="DSCEditObjectSummary"] 

这是我得到的一个错误,我想要的只是点击元素,就像所有其他元素都被 CSS_Selectors 定位一样。下图以蓝色表示“编辑详细信息...”按钮的确切行。

Edit Details Button

【问题讨论】:

  • 可能是您尝试单击的元素位于 iframe 中,因此您需要先 driver.switch_to.frame() 然后单击该元素,如果是这种情况。也可能是您不需要指定 'td[id="etc"]' 而只需要指定 ...css_selector("DSCEditObjectSummary")
  • @PeterBejan 我使用 link 作为格式化我的 css_selectors 的参考,到目前为止,我一直在指定它们的属性,例如 id、class 等,并且效果很好。我做到了,但是出于好奇尝试您提到的内容,我被抛出了相同的元素未找到错误。对于 iframe 评论,您是对的!它正在加载到 iframe 中,我不确定如何将其转换为 id 元素?
  • 你必须切换到 iframe 使用。 driver.switch_to.frame('frame locator goes here")。那么
  • * 然后像往常一样与 iframe 中的元素进行交互。使用driver.switch_to.default_content()切换回父窗口
  • 看起来问题出在定位器上。请将elemEdit = browser.find_element_by_css_selector('td[id="DSCEditObjectSummary"]') 替换为elemEdit = browser.find_element_by_css_selector('//td[@id="DSCEditObjectSummary"]')

标签: python selenium


【解决方案1】:

看起来问题可能与页面加载缓慢有关,或者正如另一位评论者提到的那样,它位于 iFrame 中等。如果您正在运行此工具,我通常会尝试使用 X/Y 坐标和 AppRobotic 等宏工具进行点击在 Windows 上。如果是页面加载缓慢的问题,我通常会尝试停止页面加载,并与页面进行一些交互,这样的事情应该适合你:

import win32com.client
from win32com.client import Dispatch
x = win32com.client.Dispatch("AppRobotic.API")
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import *

import pyautogui as py
import time, sys, os, traceback

#Launching Browser
browser = webdriver.Ie()
wait = WebDriverWait(browser, 15) #Waiting


#Laziness Functions
def clickCheck(Method, Locator, elemName):
    wait.until(EC.element_to_be_clickable((Method, Locator)))
    print(elemName + ' Clickable')

driver.get('https://www.google.com')
# wait 20 seconds
x.Wait(20000)
# scroll down a couple of times in case page javascript is waiting for user interaction
x.Type("{DOWN}")
x.Wait(2000)
x.Type("{DOWN}")
x.Wait(2000)
# forcefully stop pageload at this point
driver.execute_script("window.stop();")
# if clicking with Selenium still does not work here, use screen coordinates
x.MoveCursor(xCoord, yCoord)
x.MouseLeftClick
x.Wait(2000)

【讨论】:

    【解决方案2】:

    对于可能遇到同样问题并偶然发现这篇文章的其他人来说,我更愿意发布这个答案。正如@PeterBejan 提到的,我试图单击的元素嵌套在 iframe 中。我尝试访问 iframe,但抛出了 NoSuchFrameException。进一步挖掘发现,这个框架嵌套在其他 3 个框架中,我必须从顶层向下切换到每个框架,才能访问该元素。这是我使用的代码

    wait.until(EC.frame_to_be_available_and_switch_to_it("TopLevelFrameName"))
    wait.until(EC.frame_to_be_available_and_switch_to_it("SecondaryFrameName"))
    wait.until(EC.frame_to_be_available_and_switch_to_it("TertiaryFrameName"))
    wait.until(EC.frame_to_be_available_and_switch_to_it("FinalFrameName"))
    clickCheck(By.ID, 'ElementID', "Edit Details")
    elemEdit = browser.find_element_by_id("ElementID")
    elemEdit.click()    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-06
      • 2021-06-21
      • 1970-01-01
      • 2017-11-27
      • 2018-07-06
      相关资源
      最近更新 更多