Selenium Webdriver(Python)-无法在嵌套iframe中定位元素

时间:2019-08-11 12:45:27

标签: python selenium selenium-webdriver iframe css-selectors

我正在尝试从位于网页内的iframe中抓取一些数据。该网页的网址为https://www.nissanoflithiasprings.com/schedule-service。我正在尝试访问下图中显示的按钮:

enter image description here

当我右键单击按钮(位于iframe中)以查看源代码时,我可以看到HTML ID和名称(请参见下面的屏幕截图):

enter image description here

按钮的“ id”是“ new_customer_button”。但是,当我使用Selenium Webdriver的driver.find_element_by_id("new_customer_button")访问按钮时,代码无法在iframe中定位按钮,并引发以下错误:

NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"new_customer_button"}

下面是到目前为止我尝试过的代码:

from selenium import webdriver
chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://www.nissanoflithiasprings.com/schedule-service")

dest_iframe = driver.find_elements_by_tag_name('iframe')[0] 
driver.switch_to.frame(dest_iframe)

driver.find_element_by_id("new_customer_button")

不确定为什么会这样。任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

该元素位于多个<iframe>标签内,您需要一个一个地切换到它们。您还应该最大化窗口并使用显式等待,因为它需要一些时间来加载

from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.maximize_window()
driver.get("https://www.nissanoflithiasprings.com/schedule-service")

wait = WebDriverWait(driver, 10)

# first frame - by css selector
wait.until(ec.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, '[src^="https://consumer.xtime.com"]')))

# second frame - by ID
wait.until(ec.frame_to_be_available_and_switch_to_it('xt01'))

driver.find_element_by_id("new_customer_button")

答案 1 :(得分:0)

click()上文本为制作·年份·模型的元素,因为所需元素在嵌套的<iframe>内,因此您必须:

  • 诱导 WebDriverWait 以使所需的父框架可用并切换到
  • 诱导 WebDriverWait 以使所需的子框架可用并切换到它。
  • 为所需的element_to_be_clickable()诱导 WebDriverWait
  • 您可以使用以下解决方案:

    • 代码块:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      
      chrome_options = webdriver.ChromeOptions() 
      chrome_options.add_argument("start-maximized")
      chrome_options.add_argument('disable-infobars')
      driver = webdriver.Chrome(options=chrome_options, executable_path=r'C:\WebDrivers\chromedriver.exe')
      driver.get("https://www.nissanoflithiasprings.com/schedule-service")
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='com/scheduling']")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='consumerportal']")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.button.button--action.btn.btn-secondary#new_customer_button"))).click()
      
  • 浏览器快照:

nissan

  

在这里您可以找到有关Ways to deal with #document under iframe的相关讨论