Как работать с вложенными фреймами iframe с помощью Selenium и Python

#python-3.x #selenium #selenium-chromedriver

Вопрос:

Я пытаюсь автоматизировать ежедневную задачу, но застрял с некоторыми вложенными фреймами. Сценарий работает очень хорошо, пока часть отмены выбора всех типов документов не завершится неудачей.

Я попытался дождаться, пока элемент станет доступным для кликабельности. Кроме того, я попытался получить доступ к элементу с помощью идентификатора, css_selector и XPath, но ничего не помогло.

Я думаю, что элемент расположен во вложенных фреймах, но не может получить правильную последовательность.

Вот мой сценарий:

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

options = webdriver.ChromeOptions()
options.add_argument("disable-infobars")
#options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument('--disable-dev-shm-usage')
#options.add_argument('--disable-gpu')
options.add_argument("--start-maximized")
options.add_experimental_option("excludeSwitches",["ignore-certificate-errors"])
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

link = r"https://countyfusion10.kofiletech.us/countyweb/loginDisplay.action?countyname=TylerWV"

options.add_experimental_option("prefs", {
  "download.directory_upgrade":True,
  "safebrowsing.enabled":True,
  "download.prompt_for_download":False,
  "plugins.always_open_pdf_externally": True,
})
driver = webdriver.Chrome(executable_path='./chromedriver', options=options)
driver.get(link)

#Login as Guest
driver.find_element_by_xpath(r'//*[@id="maindiv"]/table[2]/tbody/tr[1]/td[2]/table/tbody/tr/td/center/input').click()
time.sleep(5)

#Accept Disclaimer
driver.switch_to.frame("bodyframe")
driver.find_element_by_id(r'accept').click()
time.sleep(30)

#Deselect All types
driver.switch_to.default_content()
boxes = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,r'//*[@id="elemAllNamesJSP_20"]/table/tbody/tr/td[2]/span/input[1]')))
print(boxes)
 

Ответ №1:

Я не уверен, что вам нужно было переключаться на содержимое по умолчанию, в любом случае, поскольку вы вышли из bodyframe iframe, чтобы получить доступ к элементу «коробки», вы сначала переключились на первый родительский iframe, затем на внутреннего родителя, а затем на внутреннего ребенка. Подобный этому:

 driver = webdriver.Chrome(executable_path='./chromedriver', options=options)
driver.get(link)

#Login as Guest
driver.find_element_by_xpath(r'//*[@id="maindiv"]/table[2]/tbody/tr[1]/td[2]/table/tbody/tr/td/center/input').click()

#Accept Disclaimer
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"bodyframe"))
driver.find_element_by_id(r'accept').click()

#Deselect All types
driver.switch_to.default_content()

WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"bodyframe"))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"dynSearchFrame"))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"criteriaframe"))
boxes = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,r'//*[@id="elemAllNamesJSP_20"]/table/tbody/tr/td[2]/span/input[1]')))
print(boxes)
 

Я не уверен, чего вы пытаетесь достичь, печатая веб-элемент «коробки» с print(boxes)
Также я удалил жестко закодированные задержки. Особенно 30-секундный сон, он вам не нужен. Вместо этого используйте явное ожидание webdriver.
Он будет работать намного быстрее и по-прежнему стабильно.