Вопрос-Ответ

Select iframe using Python + Selenium

Выберите iframe с помощью Python + Selenium

Итак, я был абсолютно сбит с толку относительно того, как это сделать в Selenium, и нигде не смог найти ответа, поэтому я делюсь своим опытом.

Я пытался выбрать iframe, но безуспешно (или, во всяком случае, не повторяется). HTML-это:

<iframe id="upload_file_frame" width="100%" height="465px" frameborder="0" framemargin="0" name="upload_file_frame" src="/blah/import/">
<html>
<body>
<div class="import_devices">
<div class="import_type">
<a class="secondary_button" href="/blah/blah/?source=blah">
<div class="import_choice_image">
<img alt="blah" src="/public/images/blah/import/blah.png">
</div>
<div class="import_choice_text">Blah Blah</div>
</a>
</div>
</div>
</body>
</html>

Код Python (использующий библиотеку selenium) пытался найти этот iframe, используя это:

    @timed(650)
def test_pedometer(self):
sel = self.selenium
...
time.sleep(10)
for i in range(5):
try:
if sel.select_frame("css=#upload_file_frame"): break
except: pass
time.sleep(10)
else: self.fail("Cannot find upload_file_frame, the iframe for the device upload image buttons")

Повторяющиеся сбои при каждой комбинации команд Selenium, которые я смог найти.

Случайный успех не был бы воспроизводимым, так что, возможно, это было какое-то условие гонки или что-то в этом роде? Так и не удалось найти правильный способ получить это в собственно selenium.

Переведено автоматически
Ответ 1

У меня это сработало с Python (версия 2.7), webdriver и Selenium при тестировании с iframes и попытке вставить данные в iframe:

self.driver = webdriver.Firefox()

## Give time for iframe to load ##
time.sleep(3)
## You have to switch to the iframe like so: ##
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
## Insert text via xpath ##
elem = driver.find_element_by_xpath("/html/body/p")
elem.send_keys("Lorem Ipsum")
## Switch back to the "default content" (that is, out of the iframes) ##
driver.switch_to.default_content()
Ответ 2

Если iframe это динамический узел, также можно дождаться iframe явного появления, а затем переключиться на него с помощью ExpectedConditions:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait

driver = webdriver.Chrome()
driver.get(URL)
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("iframe_name_or_id"))

Если iframe нет @id или @name его можно найти как обычный WebElement, используя driver.find_element_by_xpath(), driver.find_element_by_tag_name() и т.д..:

wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath("//iframe[@class='iframe_class']")))

Чтобы переключиться обратно с iframe:

driver.switch_to.default_content()
Ответ 3

Что, наконец, сработало для меня, так это:

        sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();")

В принципе, не используйте selenium, чтобы найти ссылку в iframe и щелкнуть по ней; используйте jQuery. Очевидно, что Selenium имеет возможность запускать произвольный фрагмент javascript (это python-selenium, я предполагаю, что исходная команда selenium - RunScript или что-то в этом роде), и как только я смогу использовать jQuery, я смогу сделать что-то вроде этого: Выбор формы, которая находится в iframe, с помощью jQuery

Ответ 4

Вам не нужно использовать JavascriptExecutor. Все, что вам нужно было сделать, это переключиться во фрейм, а затем снова переключиться, вот так:

// do stuff on main window
driver.switch_to.frame(frame_reference)
// then do stuff in the frame
driver.switch_to.default_content()
// then do stuff on main window again

Пока вы осторожны с этим, у вас никогда не возникнет проблем. Единственный раз, когда я всегда использую JavascriptExecutor, - это получить фокус окна, поскольку я думаю, что использование Javascript в этом случае более надежно.

python selenium