Selenium - iframe 的烦恼 - 无法解决

1 投票
2 回答
830 浏览
提问于 2025-04-18 06:56

我在这个问题上纠结了很久,现在终于决定来这里求助。

我有一个包含iframe的页面:

<iframe frameborder="0" allowtransparency="true" tabindex="0" src="" title="Rich text editor, listing_description" aria-describedby="cke_18" style="width:100%;height:100%">

当我使用以下xpath获取元素时:

'//*[@aria-describedby="cke_18"]'

我得到了一个网页元素,如下所示:

>>> elem
<selenium.webdriver.remote.webelement.WebElement object at 0x104327b50>
>>> elem.id
u'{3dfc8264-71bc-c948-882a-acd6a8b93ab5}'
>>> elem.is_displayed
<bound method WebElement.is_displayed of <selenium.webdriver.remote.webelement.WebElement object at 0x104327b50>>

但是,当我尝试在这个iframe中提取信息时,出现了如下错误:

追踪记录(最近的调用在最前): 文件 "<stdin>",第 1 行,在 <module> 文件 "/Applications/Spyder.app/Contents/Resources/lib/python2.7/spyderlib/widgets/externalshell/sitecustomize.py",第 560 行,在 debugfile debugger.run("runfile(%r, args=%r, wdir=%r)" % (filename, args, wdir)) 文件 "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py",第 400 行,在 run exec cmd in globals, locals 文件 "<string>",第 1 行,在 <module> 文件 "/Applications/Spyder.app/Contents/Resources/lib/python2.7/spyderlib/widgets/externalshell/sitecustomize.py",第 540 行,在 runfile execfile(filename, namespace) 文件 "/Users/jasonmellone/Documents/PythonProjects/nakedApts.py",第 88 行,在 <module> a = elem.find_element_by_xpath(".//*") 文件 "/Library/Python/2.7/site-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webelement.py",第 201 行,在 find_element_by_xpath return self.find_element(by=By.XPATH, value=xpath) 文件 "/Library/Python/2.7/site-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webelement.py",第 377 行,在 find_element {"using": by, "value": value})['value'] 文件 "/Library/Python/2.7/site-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webelement.py",第 370 行,在 _execute return self._parent.execute(command, params) 文件 "/Library/Python/2.7/site-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webdriver.py",第 166 行,在 execute self.error_handler.check_response(response) 文件 "/Library/Python/2.7/site-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/errorhandler.py",第 164 行,在 check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: 消息: u'无法找到元素: {"method":"xpath","selector":".//*"}' ; 堆栈跟踪: 在 FirefoxDriver.prototype.findElementInternal_ (file:///var/folders/8x/0msd5dd13l9453ff9739rj7w0000gn/T/tmpmH4ARe/extensions/fxdriver@googlecode.com/components/driver_component.js:8905) 在 FirefoxDriver.prototype.findChildElement (file:///var/folders/8x/0msd5dd13l9453ff9739rj7w0000gn/T/tmpmH4ARe/extensions/fxdriver@googlecode.com/components/driver_component.js:8917) 在 DelayedCommand.prototype.executeInternal_/h (file:///var/folders/8x/0msd5dd13l9453ff9739rj7w0000gn/T/tmpmH4ARe/extensions/fxdriver@googlecode.com/components/command_processor.js:10884) 在 DelayedCommand.prototype.executeInternal_ (file:///var/folders/8x/0msd5dd13l9453ff9739rj7w0000gn/T/tmpmH4ARe/extensions/fxdriver@googlecode.com/components/command_processor.js:10889) 在 DelayedCommand.prototype.execute/< (file:///var/folders/8x/0msd5dd13l9453ff9739rj7w0000gn/T/tmpmH4ARe/extensions/fxdriver@googlecode.com/components/command_processor.js:10831)

现在,我并不是一个selenium开发者,所以我对这个错误完全不懂。

当我运行以下代码时:

   elem = Helper.getElementByxPath(mydriver,'//*[@aria-describedby="cke_18"]',"ABC"); 
   mydriver.switch_to_frame(elem);

上面的代码可以运行,其中 Helper.getElementByxPath 是:

    def getElementByxPath(mydriver,xPath,valueString):

        try:

            a = mydriver.find_element_by_xpath(xPath);
            a.send_keys(valueString);
            return a;
        except:
            print "Unexpected error:", sys.exc_info()[0];
            return 0;

   a = elem.find_element_by_xpath(".//*")

这给了我以下结果:

>>> elem.id

 u'{8be4819b-f828-534a-9eb2-5b791f42b99a}'

而以下语句:

  a = elem.find_element_by_xpath(".//*")

又给了我一个巨大的错误。

让我感到沮丧的是:

  1. 我并不需要从iframe中的嵌入输入框获取信息,我只是想发送键入。
  2. 我很乐意一直按“Keys.TAB”直到到达正确的输入框,然后用Cursor.location.element.send_keys(伪代码)。
  3. 我只想在页面上输入文本,因为光标已经在正确的位置(难道我不能简单地做到这一点吗?)

我的目标只是发送键入,而不是做更复杂的事情,但我似乎无法解决这个问题,结果总是出现上面的错误。

有没有办法解决这个问题?我感到很沮丧,希望有人能给我答案。

谢谢!

2 个回答

0

Selenium只能访问当前框架中的元素。如果你想切换到更深层的框架,可以这样做:

driver.switch_to_frame(IDENTIFIER)

这里的IDENTIFIER可以是:

  • 框架的名称
  • 指向框架的网页元素引用
  • 框架的数字索引

你可以在这里查看API的详细信息:http://selenium-python.readthedocs.org/en/latest/api.html

当你在iframe中完成操作后,可以用下面的代码切换回最顶层:

driver.switch_to_default_content()
0

解决我具体问题的代码片段如下:

            elem = Helper.getElementByxPath(mydriver,".//iframe[@title='theTitleOfMyIframe']","ABC"); 
            mydriver.switch_to_frame(elem);
            elem2 = Helper.getElementByxPath(mydriver,"//body[@contentEditable='true']","ABC");

我的 xpath 函数是:

            def getElementByxPath(mydriver,xPath,valueString):

                try:

                    a = mydriver.find_element_by_xpath(xPath);
                    a.send_keys(valueString);
                    return a;
                except:
                    print "Unexpected error:", sys.exc_info()[0];
                    return 0;

一旦你确认你的 ckeditor 在范围内,你就可以运行以下代码:

  mydriver.execute_script(str("arguments[0].innerHTML = 'test'"), elem2)

这样应该就能像你预期的那样工作!希望这能帮助其他人节省时间!

撰写回答