python - 在 Selenium 上选择其他标签内的 Iframe

标签 python html selenium iframe xpath

大家好。

首先,这是一个 TL;DR 版本:

我需要在 iframe 内选择一个元素,该元素也在许多其他 HTML 标记内。

现在,实际问题:

今天我正在尝试解决工作中遇到的一个小问题。每天我都需要执行一项耗时的任务,即填写一些信息的表格。问题是每个表格都必须以完全相同的方式完成,而且我必须在单独的网页上完成此操作。几个月前,我了解了 Selenium,并尝试在网站上使用它,以便我可以自动化此过程。

问题是我遇到了问题。显然,Selenium IDE 无法识别 iframe。我尝试将代码导出到 Python 2.7 并根据我找到的一些堆栈溢出解决方案对其进行编辑,但显然没有任何效果,可能是因为我对这种事情很陌生。

iframe 位于一堆其他 HTML 标记(如表格、垃圾邮件、正文等)内,因此我不知道如何访问它。

下面是包含 iframe 的网页代码的一部分,紧接着是我尝试使用 Python 2.7 进行自动化的测试。请记住,我对 Python 完全陌生,到目前为止我只使用过 Selenium IDE 一次。

HTML 代码按部分简化:

<table class="dialog tabbed " id="tabDialog_6" cellspacing="0" cellpadding="0">

<tbody>


##A bunch of tables, spam, and bodies above.


<iframe id="descrpt_ifr" src='javascript:""' frameborder="0" style="width: 100%; height: 126px;" tabindex="78">

</iframe>
</td>
</tr>
<tr class="mceLast"><td class="mceStatusbar mceFirst mceLast">
<div id="descrpt_path_row">&nbsp;<a href="#" accesskey="x">
</a>
</div>
<a id="descrpt_resize" href="javascript:;" onclick="return false;" class="mceResize">
</a>
</td>
</tr>
</tbody>
</table>
</span>
<script>var WYSIWYGdisplayed = Boolean(window.tinyMCE != null);
</script>&nbsp;<table style="vertical-align: text-bottom; display: inline;" width="1%" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td nowrap="" style="border: none;">
<a id="oylyLink" title="Spell Check" class="button" href="javascript: void spellCheck(document.regform.LADD)" tabindex="79" onfocus="document.getElementById('oyly').onmouseover();" onblur="document.getElementById('oyly').onmouseout();">
<div id="oyly" class="button_off" onmousedown="mousedownButton('oyly');" onmouseup="highlightButton(false, 'oyly');" onmouseover="highlightButton(true, 'oyly');" onmouseout="highlightButton(false, 'oyly');" style="">
<img src="/MRimg/spell_check.png" alt="Spell Check" border="0" align="absmiddle" id="oyly_image">
</div>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="descriptionSectionHeader">Complete Description (PUBLIC)
</div>

<div class="indented"><iframe src="/tmp/alldesc_61121857.html" name="ALL_DESCS" width="702" height="170" scrolling="yes" wrap="hard"></iframe></div>   
</td>
</tr>
</tbody>
</table>

页面完整的html代码:

<table class="dialog tabbed " id="tabDialog_6" cellspacing="0" cellpadding="0">
    <script language="javascript"> tabIDs['Description'] = "tabDialog_6"; </script> 
    <tbody><tr>
       <td class="dialogMainContent">
    <div id="newDesc" class="descriptionSectionHeader"><label id="LADD_label" for="descrpt" class="">Append New Description (PUBLIC)<span class="asteriskHolder">*</span></label></div><div class="indented">
                    <script language="JavaScript">

            function combineFields () {
                  var flds = new Array();
                  var res = new Array();
                  for (var i=0; i< flds.length; i++) {
                     var fld = document.regform.elements[flds[i]];
                     if (fld != null)
                     {
                     if (fld.type == 'select-one' && fld.selectedIndex>=0 && fld.options[fld.selectedIndex].value) {
                        res.push (fld.name+'='+fld.options[fld.selectedIndex].value);
                     } else if (fld.type == 'text'  && fld.value) {
                        res.push (fld.name+'='+fld.value);
                     } else if (fld.type == 'select-multiple' && fld.selectedIndex>=0) {
                        var sel = new Array();
                        for (var j=0; j< fld.options.length; j++) {
                            if (fld.options[j].selected && fld.options[j].value) {
                                sel.push(fld.options[j].value);
                            }
                        }
                        if (sel.length> 0){res.push (fld.name+'~'+sel.join('|'));}
                     } else if (fld.type == 'checkbox' && fld.checked) {
                           res.push (fld.name+'='+fld.value);
                     } else if (fld.type == 'textarea' && fld.value) {
                           res.push (fld.name+'~'+fld.value);
                     }
                   }
                   }
                   var ret = encodeURIComponent(res.join(','));
                   ret = '&SOLFILTR=' + (ret || "__nothing__");
                   return ret;
           }


                     function searchsolutions() {
                       var height = 530;
                       var width = 660;
                       var str = combineFields();

                       window.open('/MRcgi/MRshowsolutions_page.pl?USER=UserPROJECTID=2&MRP=5pIpUWj0&REGPAGE=0&SELECTSOLUTION=1&SESS_ID=9c91e9288993272a387fbe9f9f7c0fac&SAVEDNAME=SOL'+str, 'solsearch', 'top=176,left=133,width=' + width + ',height=' + height + ',status=yes,toolbar=no,directories=no,menubar=no,scrollbars=yes,resizable=yes');
                    }
                    </script>
                <table class="inlineDialogHeading indented">
    <tbody><tr>
    <td><table style="vertical-align: text-bottom; display: inline;" width="1%" cellpadding="0" cellspacing="0" border="0"><tbody><tr><td nowrap="" style="border: none;"><a id="searchKBButtonLink" title="Search Knowledge Base" class="button" href="javascript:searchsolutions();" tabindex="77" onfocus="document.getElementById('searchKBButton').onmouseover();" onblur="document.getElementById('searchKBButton').onmouseout();"><div id="searchKBButton" class="button_off" onmousedown="mousedownButton('searchKBButton');" onmouseup="highlightButton(false, 'searchKBButton');" onmouseover="highlightButton(true, 'searchKBButton');" onmouseout="highlightButton(false, 'searchKBButton');" style=""><img src="/MRimg/knowledge_base.png" alt="Search Knowledge Base" border="0" align="absmiddle" id="searchKBButton_image"> <span id="searchKBButton_textSpan" style=" height: 18px; cursor: pointer;">Search Knowledge Base</span></div></a></td></tr></tbody></table></td></tr>
    </tbody></table>
    <textarea name="LADD" title="Description (PUBLIC)" cols="85" id="descrpt" tabindex="-1" onkeypress="addAutoSpell(document.regform.LADD)" style="height: 170px; width: 702px; display: none;" class="wysiwyg"></textarea><span id="descrpt_parent" class="mceEditor defaultSkin"><table id="descrpt_tbl" class="mceLayout" cellspacing="0" cellpadding="0" style="width: 702px; height: 170px;"><tbody><tr class="mceFirst"><td class="mceToolbar mceLeft mceFirst mceLast"><a href="#" accesskey="q" title="Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X"><!-- IE --></a><table id="descrpt_toolbar1" class="mceToolbar mceToolbarRow1 Enabled" cellpadding="0" cellspacing="0" align=""><tbody><tr><td class="mceToolbarStart mceToolbarStartButton mceFirst"><span><!-- IE --></span></td><td><a id="descrpt_newdocument" href="javascript:;" class="mceButton mceButtonEnabled mce_newdocument" onmousedown="return false;" onclick="return false;" title="New document"><span class="mceIcon mce_newdocument"></span></a></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_cut" href="javascript:;" class="mceButton mceButtonEnabled mce_cut" onmousedown="return false;" onclick="return false;" title="Cut"><span class="mceIcon mce_cut"></span></a></td><td><a id="descrpt_copy" href="javascript:;" class="mceButton mceButtonEnabled mce_copy" onmousedown="return false;" onclick="return false;" title="Copy"><span class="mceIcon mce_copy"></span></a></td><td><a id="descrpt_paste" href="javascript:;" class="mceButton mceButtonEnabled mce_paste" onmousedown="return false;" onclick="return false;" title="Paste"><span class="mceIcon mce_paste"></span></a></td><td><a id="descrpt_undo" href="javascript:;" class="mceButton mce_undo mceButtonEnabled" onmousedown="return false;" onclick="return false;" title="Undo (Ctrl+Z)"><span class="mceIcon mce_undo"></span></a></td><td><a id="descrpt_redo" href="javascript:;" class="mceButton mce_redo mceButtonDisabled" onmousedown="return false;" onclick="return false;" title="Redo (Ctrl+Y)"><span class="mceIcon mce_redo"></span></a></td><td><span class="mceSeparator"></span></td><td><table id="descrpt_fontselect" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled mce_fontselect"><tbody><tr><td class="mceFirst"><a id="descrpt_fontselect_text" href="javascript:;" class="mceText mceTitle" onclick="return false;" onmousedown="return false;">Font family</a></td><td class="mceLast"><a id="descrpt_fontselect_open" tabindex="-1" href="javascript:;" class="mceOpen" onclick="return false;" onmousedown="return false;"><span></span></a></td></tr></tbody></table></td><td><table id="descrpt_fontsizeselect" cellpadding="0" cellspacing="0" class="mceListBox mceListBoxEnabled mce_fontsizeselect"><tbody><tr><td class="mceFirst"><a id="descrpt_fontsizeselect_text" href="javascript:;" class="mceText mceTitle" onclick="return false;" onmousedown="return false;">Font size</a></td><td class="mceLast"><a id="descrpt_fontsizeselect_open" tabindex="-1" href="javascript:;" class="mceOpen" onclick="return false;" onmousedown="return false;"><span></span></a></td></tr></tbody></table></td><td><span class="mceSeparator"></span></td><td><table id="descrpt_forecolor" class="mceSplitButton mceSplitButtonEnabled mce_forecolor" cellpadding="0" cellspacing="0" onmousedown="return false;" title="Select text color"><tbody><tr><td class="mceFirst"><a id="descrpt_forecolor_action" href="javascript:;" class="mceAction mce_forecolor" onclick="return false;" onmousedown="return false;" title="Select text color"><span class="mceAction mce_forecolor"></span><div id="descrpt_forecolor_preview" class="mceColorPreview" style="background-color: rgb(136, 136, 136);"></div></a></td><td class="mceLast"><a id="descrpt_forecolor_open" href="javascript:;" class="mceOpen mce_forecolor" onclick="return false;" onmousedown="return false;" title="Select text color"><span class="mceOpen mce_forecolor"></span></a></td></tr></tbody></table></td><td><table id="descrpt_backcolor" class="mceSplitButton mceSplitButtonEnabled mce_backcolor" cellpadding="0" cellspacing="0" onmousedown="return false;" title="Select background color"><tbody><tr><td class="mceFirst"><a id="descrpt_backcolor_action" href="javascript:;" class="mceAction mce_backcolor" onclick="return false;" onmousedown="return false;" title="Select background color"><span class="mceAction mce_backcolor"></span><div id="descrpt_backcolor_preview" class="mceColorPreview" style="background-color: rgb(136, 136, 136);"></div></a></td><td class="mceLast"><a id="descrpt_backcolor_open" href="javascript:;" class="mceOpen mce_backcolor" onclick="return false;" onmousedown="return false;" title="Select background color"><span class="mceOpen mce_backcolor"></span></a></td></tr></tbody></table></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_bold" href="javascript:;" class="mceButton mceButtonEnabled mce_bold" onmousedown="return false;" onclick="return false;" title="Bold (Ctrl+B)"><span class="mceIcon mce_bold"></span></a></td><td><a id="descrpt_italic" href="javascript:;" class="mceButton mceButtonEnabled mce_italic" onmousedown="return false;" onclick="return false;" title="Italic (Ctrl+I)"><span class="mceIcon mce_italic"></span></a></td><td><a id="descrpt_underline" href="javascript:;" class="mceButton mceButtonEnabled mce_underline" onmousedown="return false;" onclick="return false;" title="Underline (Ctrl+U)"><span class="mceIcon mce_underline"></span></a></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_justifyleft" href="javascript:;" class="mceButton mceButtonEnabled mce_justifyleft" onmousedown="return false;" onclick="return false;" title="Align left"><span class="mceIcon mce_justifyleft"></span></a></td><td><a id="descrpt_justifycenter" href="javascript:;" class="mceButton mceButtonEnabled mce_justifycenter" onmousedown="return false;" onclick="return false;" title="Align center"><span class="mceIcon mce_justifycenter"></span></a></td><td><a id="descrpt_justifyright" href="javascript:;" class="mceButton mceButtonEnabled mce_justifyright" onmousedown="return false;" onclick="return false;" title="Align right"><span class="mceIcon mce_justifyright"></span></a></td><td><a id="descrpt_justifyfull" href="javascript:;" class="mceButton mceButtonEnabled mce_justifyfull" onmousedown="return false;" onclick="return false;" title="Align full"><span class="mceIcon mce_justifyfull"></span></a></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_bullist" href="javascript:;" class="mceButton mceButtonEnabled mce_bullist" onmousedown="return false;" onclick="return false;" title="Unordered list"><span class="mceIcon mce_bullist"></span></a></td><td><a id="descrpt_numlist" href="javascript:;" class="mceButton mceButtonEnabled mce_numlist" onmousedown="return false;" onclick="return false;" title="Ordered list"><span class="mceIcon mce_numlist"></span></a></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_outdent" href="javascript:;" class="mceButton mce_outdent mceButtonDisabled" onmousedown="return false;" onclick="return false;" title="Outdent"><span class="mceIcon mce_outdent"></span></a></td><td><a id="descrpt_indent" href="javascript:;" class="mceButton mceButtonEnabled mce_indent" onmousedown="return false;" onclick="return false;" title="Indent"><span class="mceIcon mce_indent"></span></a></td><td><span class="mceSeparator"></span></td><td><a id="descrpt_table" href="javascript:;" class="mceButton mceButtonEnabled mce_table" onmousedown="return false;" onclick="return false;" title="Inserts a new table"><span class="mceIcon mce_table"></span></a></td><td><a id="descrpt_hr" href="javascript:;" class="mceButton mceButtonEnabled mce_hr" onmousedown="return false;" onclick="return false;" title="Insert horizontal ruler"><span class="mceIcon mce_hr"></span></a></td><td><a id="descrpt_charmap" href="javascript:;" class="mceButton mceButtonEnabled mce_charmap" onmousedown="return false;" onclick="return false;" title="Insert custom character"><span class="mceIcon mce_charmap"></span></a></td><td><a id="descrpt_link" href="javascript:;" class="mceButton mce_link mceButtonEnabled" onmousedown="return false;" onclick="return false;" title="Insert/edit link"><span class="mceIcon mce_link"></span></a></td><td><a id="descrpt_image" href="javascript:;" class="mceButton mceButtonEnabled mce_image" onmousedown="return false;" onclick="return false;" title="Insert/edit image"><span class="mceIcon mce_image"></span></a></td><td class="mceToolbarEnd mceToolbarEndButton mceLast"><span><!-- IE --></span></td></tr></tbody></table><a href="#" accesskey="z" title="Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X" onfocus="tinyMCE.getInstanceById('descrpt').focus();"><!-- IE --></a></td></tr><tr><td class="mceIframeContainer mceFirst mceLast">


##THE IFRAME IS RIGHT IN THIS SECTION



<iframe id="descrpt_ifr" src='javascript:""' frameborder="0" style="width: 100%; height: 126px;" tabindex="78">

</iframe>
</td>
</tr>
<tr class="mceLast"><td class="mceStatusbar mceFirst mceLast">
<div id="descrpt_path_row">&nbsp;<a href="#" accesskey="x">
</a>
</div>
<a id="descrpt_resize" href="javascript:;" onclick="return false;" class="mceResize">
</a>
</td>
</tr>
</tbody>
</table>
</span>
<script>var WYSIWYGdisplayed = Boolean(window.tinyMCE != null);
</script>&nbsp;<table style="vertical-align: text-bottom; display: inline;" width="1%" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td nowrap="" style="border: none;">
<a id="oylyLink" title="Spell Check" class="button" href="javascript: void spellCheck(document.regform.LADD)" tabindex="79" onfocus="document.getElementById('oyly').onmouseover();" onblur="document.getElementById('oyly').onmouseout();">
<div id="oyly" class="button_off" onmousedown="mousedownButton('oyly');" onmouseup="highlightButton(false, 'oyly');" onmouseover="highlightButton(true, 'oyly');" onmouseout="highlightButton(false, 'oyly');" style="">
<img src="/MRimg/spell_check.png" alt="Spell Check" border="0" align="absmiddle" id="oyly_image">
</div>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="descriptionSectionHeader">Complete Description (PUBLIC)
</div>

<div class="indented"><iframe src="/tmp/alldesc_61121857.html" name="ALL_DESCS" width="702" height="170" scrolling="yes" wrap="hard"></iframe></div>   
</td>
</tr>
</tbody>
</table>

我的 Selenium IDE 代码导出到 python。

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class CasoDeTesteStiMEmPython(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "THE WEBPAGE I NEED TO FILL THE FORM"
        self.verificationErrors = []
        self.accept_next_alert = True

    def test_caso_de_teste_sti_m_em_python(self):
        driver = self.driver
        driver.get(self.base_url + "/MRcgi/MRhomepage.pl?USER=yferreir&PROJECTID=3&MRP=bmKXVpJkDK&OPTION=none&WRITECACHE=1&FIRST_TIME_IN_FP=1&FIRST_TIME_IN_PROJ=1&REMEMBER_SCREEN=1&")
        driver.find_element_by_id("SEARCHS").clear()
        driver.find_element_by_id("SEARCHS").send_keys("404905")
        driver.find_element_by_id("splitbutton1-button").click()
        # ERROR: Caught exception [ERROR: Unsupported command [waitForPopUp | details404905 | 100000]]
        # ERROR: Caught exception [ERROR: Unsupported command [selectWindow | name=details404905 | ]]
        driver.find_element_by_id("editButton_image").click()
        Select(driver.find_element_by_id("status")).select_by_visible_text("Under Investigation")
         ##RIGHT HERE IS WHERE I NEED TO SELECT THE IFRAME
         ##THE FOLLOWING PARTS OF THE CODE WITH ## ARE FROM A STACKOVERFLOW SOLUTION I TRIED


        ## 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("descrpt_ifr"))
        ## Insert text via xpath ##
        elem = driver.find_element_by_xpath("//*[@id="tinymce"]/p")
        elem.send_keys("WHAT I NEED TO WRITE IN THE ELEMENT INSIDE THE IFRAME")
        ## Switch back to the "default content" (that is, out of the iframes) ##
        driver.switch_to_default_content()
        # ERROR: Caught exception [ERROR: Unsupported command [selectWindow | name=details404905 | ]]
        driver.find_element_by_id("goButton_textSpan").click()
        # ERROR: Caught exception [ERROR: Unsupported command [selectWindow | null | ]]
        driver.find_element_by_id("SEARCHS").clear()
        driver.find_element_by_id("SEARCHS").send_keys("404905")
        driver.find_element_by_id("splitbutton1-button").click()
        # ERROR: Caught exception [ERROR: Unsupported command [waitForPopUp | details404905 | 100000]]
        # ERROR: Caught exception [ERROR: Unsupported command [selectWindow | name=details404905 | ]]
        driver.find_element_by_id("editButton_textSpan").click()
        Select(driver.find_element_by_id("status")).select_by_visible_text("Solved")
        driver.find_element_by_id("tab_1").click()
        Select(driver.find_element_by_id("userfield22")).select_by_visible_text("Administration")
        driver.find_element_by_id("userfield24").clear()
        driver.find_element_by_id("userfield24").send_keys("Cancelamento realizado com sucesso.")
        driver.find_element_by_id("goButton_textSpan").click()

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

我尝试使用 iframe 的 ID“descrpt_ifr”和以下 Xpath:

Iframe Xpath://*[@id="descrpt_ifr"].

Iframe 内的元素我想使用 Xpath://*[@id="tinymce"]/p.

最佳答案

看起来用于切换到 iframe 的代码行导致了错误

driver.switch_to_frame(driver.find_element_by_tag_name("descrpt_ifr"))

“descrpt_ifr”不是标签名称。将其更改为

driver.switch_to_frame(driver.find_element_by_id("descrpt_ifr"))

或者使用 xpath 来标识 iframe,以防 id 存在多个匹配节点。

关于python - 在 Selenium 上选择其他标签内的 Iframe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39877503/

相关文章:

javascript - 隐藏和显示侧切换

jquery - 当用户在 DIV 外部单击时,使用 jQuery 隐藏 DIV

c# - StdOut 充斥着 'C:\fakepath' 警告,整数除法可能会慢得多,如果可能,请尝试使用 uints 通过 C# 使用 Selenium

Python Selenium : Unable to locate the element (//input[@type ='file' ]')

selenium - xpath - 选择包含 CLASS 名称中的文本的元素

python - 需要从 selenium 服务器转储带有元素 id 的整个 DOM 树

python - 单行中的两个时间戳字符串用于转换日期时间

python - 如何向量化基于最后 x 行数据的 Pandas 计算

javascript - jQuery 发送多个表单数据

javascript - ng-repeat 将空白行返回到表中