NaiboWang/EasySpider · error · NoSuchElementException

Element {value} not found in any frame or iframe

Error message

Element {value} not found in any frame or iframe

What it means

Raised by MyChrome.find_element_recursive (ExecuteStage/myChrome.py:92) as a selenium NoSuchElementException after it has iterated every <iframe> and recursed into nested iframes without finding a single matching element. This is the Python runtime-stage counterpart of error 0, used during actual task execution rather than the Electron design-time UI.

Source

Thrown at ExecuteStage/myChrome.py:92

                except StaleElementReferenceException:
                    # If the frame has been refreshed, we need to switch to the parent frame first,
                    self.switch_to.parent_frame()
                    self.switch_to.frame(frame)
                try:
                    # !!! Attempt to find the element in the current frame, not the context (iframe environment will not change to default), therefore we use super().find_element instead of self.find_element
                    element = super(MyChrome, self).find_element(by=by, value=value)
                    return element
                except NoSuchElementException:
                    # Recurse into nested iframes
                    nested_frames = super(MyChrome, self).find_elements(By.CSS_SELECTOR, "iframe")
                    if nested_frames:
                        element = self.find_element_recursive(by, value, nested_frames)
                        if element:
                            return element
            except Exception as e:
                print(f"Exception while processing frame: {e}")

        raise NoSuchElementException(f"Element {value} not found in any frame or iframe")

    def find_element(self, by=By.ID, value=None, iframe=False):
        self.switch_to.default_content()  # Switch back to the main document
        self.iframe_env = False
        if iframe:
            frames = self.find_elements(By.CSS_SELECTOR, "iframe")
            if not frames:
                raise NoSuchElementException(f"No iframes found in the current page while searching for {value}")
            self.iframe_env = True
            element = self.find_element_recursive(by, value, frames)
        else:
            # Find element in the main document as normal
            element = super(MyChrome, self).find_element(by=by, value=value)
        return element

    # def find_elements(self, by=By.ID, value=None, iframe=False):
    #     # 在这里改变查找元素的行为
    #     if self.iframe_env:

View on GitHub (pinned to 191bd6d754)

Solutions

  1. Re-record the XPath against the current live page and confirm it is inside an iframe.
  2. Insert an explicit wait (WebDriverWait + EC.frame_to_be_available_and_switch_to_it, then element_to_be_clickable) before the find.
  3. Ensure pageLoadStrategy / manual sleeps give the iframe content time to render, since EasySpider sets pageLoadStrategy='none'.
  4. For cross-origin iframes, verify Selenium can actually switch into them; otherwise use JS extraction.

Example fix

# before
el = driver.find_element(By.XPATH, xpath, iframe=True)

# after
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10).until(
    EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, 'iframe')))
el = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.XPATH, xpath)))
driver.switch_to.default_content()
Defensive patterns

Strategy: try-catch

Validate before calling

from selenium.common.exceptions import NoSuchElementException
frames = driver.find_elements(By.CSS_SELECTOR, 'iframe')
if not frames:
    raise NoSuchElementException('page has no iframes to search')

Try / catch

from selenium.common.exceptions import NoSuchElementException
try:
    el = driver.find_element(By.XPATH, xpath, iframe=True)
except NoSuchElementException as e:
    if 'not found in any frame or iframe' in str(e):
        el = None  # graceful skip / log
    else:
        raise

Prevention

When it happens

Trigger: driver.find_element(by, value, iframe=True) calls find_element_recursive(by, value, frames). For each frame it switch_to.frame(frame), then super().find_element(by=by, value=value); on NoSuchElementException it gathers nested iframes and recurses. When the loop ends with no element, it raises NoSuchElementException(f'Element {value} not found in any frame or iframe').

Common situations: Task runs against a page whose iframe content is lazy-loaded or behind interaction; the recorded XPath is stale after a site redesign; cross-origin iframes block Selenium's switch_to.frame; the element is in a shadow DOM.

Related errors


AI-assisted analysis of NaiboWang/EasySpider@191bd6d754 (2026-08-13). Data as JSON: /api/errors/ea68aa420230cc67. Report an issue: GitHub.