0

I am using an undetectable Chrome Selenium webdriver in python to try and capture all iframe elements within the div tag with the px-captcha id. The html section I am trying to get from the whole page source looks as such:

<div id="px-captcha" role="region" aria-label="Human challenge" style="display: block; min-width: 310px;">
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: block; width: 100%; height: 100px; border: 0; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <iframe style="display: none; width: 100%; height: 100px; border: 0px; user-select: none;" token="464ad1a7b7ed017f8c60542b859c5333648d76b8ec128a4f886c558900ffbe63dda2831825532a9be2d1f224eee47121e522391c7dcd7c55e86e1f17ebe944b7" title="Human verification challenge"></iframe>
    <p id="ejjpkyuhrAUbSZp" role="alert" style="color: #e50000; display: inline-block; margin: 0; vertical-align: middle;"></p>
</div>

I manage to get the px-captcha id with:

element = driver.find_element(By.ID,'px-captcha')

This gives me a WebElement from which I want to get all the iframe elements. I tried it with this but it fails:

iframes = element.find_element(By.TAG_NAME,'iframe')

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"iframe"}

EDIT

The desired output is a list of the iframe WebElements similar to the type given by element = driver.find_element(By.ID,'px-captcha')

geds133
  • 1,503
  • 5
  • 20
  • 52
  • I think it can help you https://stackoverflow.com/questions/40022010/find-element-by-tag-name-within-element-by-tag-name-selenium – Visitation Jan 17 '22 at 19:00
  • I tried using CSS_SELECTOR and I get this `selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"iframe"} ` – geds133 Jan 17 '22 at 19:51

2 Answers2

0

Almost all the descendant iframes are having:

style="display: none;

sans one.


To get the count of all the descendant iframes you need to induce WebDriverWait for the presence_of_all_elements_located() and you can use the following Locator Strategy:

element = driver.find_element(By.ID,'px-captcha')
print(len(WebDriverWait(element, 20).until(EC.presence_of_all_elements_located((By.TAG_NAME, "iframe")))))
  

Note : You have to add the following imports :

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • That's great thanks. Is there any way to get this an a WebElement. The output is this: `[{}, {}, {}, {}, {}, {}, {}, {'ontouchmove': {}, 'ontouchstart': {}}, {}, {}]` – geds133 Jan 17 '22 at 23:56
  • Or 10 if if include the print and the length – geds133 Jan 17 '22 at 23:56
  • @geds133 Nopes, I'm not sure what you tend to mean through `{}`, `'ontouchmove': {}`, `'ontouchstart': {}`. But yes, you can print any of the attributes. – undetected Selenium Jan 18 '22 at 00:03
  • To explain, the point is I am using `ActionChains` to press and hold a button which I need an element for. I don't think this can be done without having the element. Does this make sense? – geds133 Jan 18 '22 at 09:52
  • @geds133 IMO, using _`ActionChains`_ to press and hold a button sounds to be different question all together. Feel free to raise a new question as per your new requirement. – undetected Selenium Jan 18 '22 at 11:03
  • I have the `ActionChains` and press and hold set up, I don't need that solution. What I need is the `iframe` element that has `'ontouchmove': {}, 'ontouchstart': {}` as a WebElement. – geds133 Jan 18 '22 at 14:08
  • Let's say it's item 2 in the list, is there a way to get the 2nd `iframe` – geds133 Jan 18 '22 at 14:18
  • @geds133 I don't see any `iframe` element that has `'ontouchmove': {}`, `'ontouchstart': {}` as a WebElement atleast within the HTML you have shared within the question. – undetected Selenium Jan 18 '22 at 14:18
  • _Let's say it's item 2 in the list, is there a way to get the 2nd iframe_: Sounds like a different question all together. – undetected Selenium Jan 18 '22 at 14:19
  • Sorry if I am being unclear, my lack of experience with this tool may means I am misunderstanding. What is that `'ontouchmove': {}, 'ontouchstart': {}` within the output? – geds133 Jan 18 '22 at 14:19
  • As the question states that I want all the `iframe` elements but the output is a list of dictionaries? – geds133 Jan 18 '22 at 14:20
  • `element = driver.find_element(By.ID,'px-captcha')` gives me a WebElement. – geds133 Jan 18 '22 at 14:22
  • 1
    Let's discuss the issue in [Selenium](https://chat.stackoverflow.com/rooms/223360/selenium) room. – undetected Selenium Jan 18 '22 at 14:25
  • I'm afraid I can't accept this answer and it's not given me the desired output. – geds133 Jan 18 '22 at 16:46
0

Try that (Python):

        try:
            iframes = driver.find_elements(By.TAG_NAME,'iframe')
            for frames in iframes:
                print(frames.get_attribute('....'))
        except Exception as e:
            raise e

(Replace '....' by what you want)

  • Remeber "find_elements" is array, so you need a for or something like that.

  • To interact with everything inside the frame you need:

    driver.switch_to.frame(iframe)

  • You can return to main frame with:

    driver.switch_to.default_content()

boludoz
  • 36
  • 4