Selenium:正确的定位器,但不能与元素交互(输入字段)

Posted

技术标签:

【中文标题】Selenium:正确的定位器,但不能与元素交互(输入字段)【英文标题】:Selenium: Correct locator but cannot interact with the element (input-field) 【发布时间】:2021-11-16 14:20:47 【问题描述】:

我尝试使用以下脚本与输入字段交互:


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep


username = "****"
password = "****"

url = "https://www.wikifolio.com/dynamic/de/de/login/login?ReturnUrl=/de/de/home&_=1632037782306"

driver = webdriver.Chrome(executable_path=r'\Users\Benjamin\Downloads\chromedriver_win32\chromedriver.exe')
wait = WebDriverWait(driver, 20)

driver.get(url)

driver.find_element_by_name("Username").send_keys(username)
driver.find_element_by_name("Password").send_keys(password)

driver.find_element_by_css_selector("button").click()

driver.get("https://www.wikifolio.com/de/de/meine-wikifolios/trade/wf00wiking")

wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".c-disclaimer .js-disclaimer__abort, .c-disclaimer .js-disclaimer__change"))).click()


wait.until(EC.visibility_of_element_located((By.XPATH, "//a[@data-description='AKER CARB.CAPT.AS NK1']"))).click()

wait.until(EC.presence_of_element_located((By.XPATH, "//div[@id='trading-modal-root' and(contains(@style,'block'))]//select[@class='js-order-type-select order-type-selector']")))
select1 = Select(driver.find_element_by_xpath("//div[@id='trading-modal-root' and(contains(@style,'block'))]//select[@class='js-order-type-select order-type-selector']"))


select1.select_by_value('quote')


#to select purchase or sale action:
select2 = Select(driver.find_element_by_xpath("//div[@id='trading-modal-root' and(contains(@style,'block'))]//select[@class='js-order-type-buysell order-buysell-selector']"))

# select by value "buy"
select2.select_by_value('buy')




buttonnew = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div[4]/div/div/div/div/div[2]/div[3]/div/div/div[2]/div[2]/input")))

newaction = ActionChains(driver)
newaction.move_to_element(buttonnew).send_keys(int(22)).perform()

脚本执行正确,除非它到达最后一部分:

buttonnew = wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div[3]/div[4]/div/div/div/div/div[2]/div[3]/div/div/div[2]/div[2]/input")))

newaction = ActionChains(driver)
newaction.move_to_element(buttonnew).send_keys(int(22)).perform()

这里执行停止。

我用浏览器检查了 XPATH。它是独一无二的。我通过“检查”检查了 Chrome,然后按 >CRTL + F

这是一个屏幕截图,Chrome 确实找到了定位器,而且它似乎是独一无二的:

这似乎表明,XPATH 是正确的,这不是“找到”正确 XPATH 的问题,而是代码执行或错误编程的问题。

我还想知道,输入字段是否包装在 Shadow DOM 或任何其他形式的隐藏结构中。

但如果是这种情况,为什么在前面的步骤中可以选择所有其他字段(如从下拉列表中选择)?

为了让您检查是否正确,我将提供该面板的完整 html(因为它是在该页面中打开的窗口):

<div>
            <div id="trade-dialog-container">
    <div id="trading-modal-root" role="dialog" class="modal fade publish trading-modal-root in" tabindex="-1" style="display: block; padding-right: 17px;">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="authorization-request-panel" style="display: none;">
                    <div class="spinner-modal-wrapper">
                        <div class="spinner"></div>
                    </div>
                </div>
                <div class="trading-panel clearfix" style="">
                    <div class="trading-panel-close modal-close-button" data-dismiss="modal">
                        <i class="icon-close4"></i>
                    </div>
                    <div class="col-xs-12 col-sm-6 col-sm-push-6 col-md-push-6 col-lg-push-6 trading-panel-preview-col trade-panel-col">
                        <div class="trading-panel-preview">
                            <div class="trading-panel-preview-wrapper">
                                <div id="trade-main-modal-header" class="trading-panel-header">
            <h4 class="trade-popup-title-shortdesc">AKER CARB.CAPT.AS NK1</h4>
            <span class="trade-popup-title-sub">
                <span id="js-underlying-isin" data-issuer="1900">
                    NO0010890304 (L&amp;S Kurse)
                </span>
            </span>
        </div>
                                <div class="row trading-panel-price-container">
                                    <div class="col-xs-6 trading-panel-price-wrapper">
                                        <div class="trading-panel-price">
                                            <div class="currentBid text-center">2,392<small>EUR</small></div>
                                            <span class="trading-panel-price-sub">Verkaufskurs (Bid)</span>
                                        </div>
                                    </div>
                                    <div class="col-xs-6 trading-panel-price-wrapper">
                                        <div class="trading-panel-price">
                                            <div class="currentAsk text-center">2,423<small>EUR</small></div>
                                            <span class="trading-panel-price-sub">Kaufkurs (Ask)</span>
                                        </div>
                                    </div>
                                </div>
                                <div class="trading-panel-summary">
                                    <table class="trading-summary-panel">
                                        <tbody>
                                            <tr class="js-switch-nobuysell-row" style="display: none;">
                                                <td colspan="2">Bestand (aktuell)</td>
                                                <td class="text-bold text-right">
                                                    <span class="js-amount-underlying">14.477</span>&nbsp;Stk.
                                                </td>
                                            </tr>
                                            <tr style="" class="js-switch-buysell-row">
                                                <td>Bestand</td>
                                                <td class="text-right trading-prev-value">
                                                    <span class="js-amount-underlying">14.477</span>&nbsp;Stk.
                                                    <i class="icon-right"></i>
                                                </td>
                                                <td class="text-bold text-right js-hideable-cell" style="visibility: visible;">
                                                    <span class="js-trade-amount-sum">14.478</span>&nbsp;Stk.
                                                </td>
                                            </tr>
                                            <tr class="js-switch-nobuysell-row" style="display: none;">
                                                <td colspan="2">Cash (aktuell)</td>
                                                <td class="text-bold text-right">
                                                    <span data-value="264258.715" class="trade-popup-wikifolio-cash">264.258,715</span>
                                                </td>
                                            </tr>
                                            <tr style="" class="js-switch-buysell-row">
                                                <td>Cash</td>
                                                <td class="text-right trading-prev-value">
                                                    <span data-value="264258.715" class="trade-popup-wikifolio-cash">264.258,715</span>
                                                    <i class="icon-right"></i>
                                                </td>
                                                <td class="text-bold text-right js-hideable-cell" style="visibility: visible;">
                                                    <span data-value="264258.715" class="trade-popup-cash-after-trade" data-cash="264256.292">264.256,292</span>&nbsp;*
                                                </td>
                                            </tr>
                                            <tr>
                                                <td colspan="2">Orderwert</td>
                                                <td class="text-bold text-right js-hideable-cell" style="visibility: visible;">
                                                    <span class="js-order-value">2,423</span><span class="js-order-value-hidden" style="display: none;">&nbsp;*</span>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                                <div class=" row trading-panel-notice hidden-xs">
                                    <div class="col-sm-6">
                                        Alle Preise in EUR
                                    </div>
                                    <div class="col-sm-6 text-right">
                                        * abhängig vom Ausführungspreis
                                    </div>
                                </div>
                                <div class="trading-panel-message-container hidden-xs">
                                    <ul class="list-unstyled"></ul>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="col-xs-12 col-sm-6 col-sm-pull-6 col-md-pull-6 col-lg-pull-6 trading-panel-detail-col trade-panel-col">
                        <div class="trading-panel-settings">
                            <div class="trading-panel-settings-wrapper">
                                <div class="row u-mb-3">
                                    <div class="col-xs-6">
                                        <div class="dropdown bootstrap-select js-order-type-select order-type-selector bs3" style="width: 100%;"><select class="js-order-type-select order-type-selector" style="opacity: 0" data->
                                            <option value="quote" selected="selected">Quote</option>
                                            <option value="limit">Limit</option>
                                                <option value="stop">Stop-Limit</option>
                                        </select><button type="button" tabindex="-1" class="btn dropdown-toggle btn-default" data-toggle="dropdown" role="combobox" aria-owns="bs-select-5" aria-haspopup="listbox" aria-expanded="false" title="Quote"><div class="filter-option"><div class="filter-option-inner"><div class="filter-option-inner-inner">Quote</div></div> </div><span class="bs-caret"><svg xmlns="http://www.w3.org/2000/svg"   viewBox="0 0 8 5"><polyline fill="none" stroke="#BBC4C7" stroke- points="2.5 -.5 5.5 2.5 2.5 5.5" transform="rotate(90 4 2.5)"></polyline></svg></span></button><div class="dropdown-menu open" style="max-height: 592px; overflow: hidden; min-height: 0px;"><div class="inner open" role="listbox" id="bs-select-5" tabindex="-1" aria-activedescendant="bs-select-5-0" style="max-height: 592px; overflow-y: auto; min-height: 0px;"><ul class="dropdown-menu inner " role="presentation" style="margin-top: 0px; margin-bottom: 0px;"><li class="selected active"><a role="option" class="dropdown-item active selected" id="bs-select-5-0" tabindex="0" aria-setsize="3" aria-posinset="1" aria-selected="true"><span class="text">Quote</span></a></li><li><a role="option" class="dropdown-item" id="bs-select-5-1" tabindex="0"><span class="text">Limit</span></a></li><li><a role="option" class="dropdown-item" id="bs-select-5-2" tabindex="0"><span class="text">Stop-Limit</span></a></li></ul></div></div></div>
                                    </div>
                                    <div class="col-xs-6">
                                        <div class="dropdown bootstrap-select js-order-type-buysell order-buysell-selector bs3" style="width: 100%;"><select class="js-order-type-buysell order-buysell-selector" style="opacity: 0" data- tabindex="null">
                                            <option selected="selected">Bitte wählen...</option>
                                            <option value="buy">Kauf</option>
                                            <option value="sell">Verkauf</option>
                                        </select><button type="button" tabindex="-1" class="btn dropdown-toggle btn-default" data-toggle="dropdown" role="combobox" aria-owns="bs-select-4" aria-haspopup="listbox" aria-expanded="false" title="Kauf"><div class="filter-option"><div class="filter-option-inner"><div class="filter-option-inner-inner">Kauf</div></div> </div><span class="bs-caret"><svg xmlns="http://www.w3.org/2000/svg"   viewBox="0 0 8 5"><polyline fill="none" stroke="#BBC4C7" stroke- points="2.5 -.5 5.5 2.5 2.5 5.5" transform="rotate(90 4 2.5)"></polyline></svg></span></button><div class="dropdown-menu open" style="max-height: 592px; overflow: hidden; min-height: 0px;"><div class="inner open" role="listbox" id="bs-select-4" tabindex="-1" aria-activedescendant="bs-select-4-1" style="max-height: 592px; overflow-y: auto; min-height: 0px;"><ul class="dropdown-menu inner " role="presentation" style="margin-top: 0px; margin-bottom: 0px;"><li><a role="option" class="dropdown-item" id="bs-select-4-0" tabindex="0"><span class="text">Bitte wählen...</span></a></li><li class="selected active"><a role="option" class="dropdown-item active selected" id="bs-select-4-1" tabindex="0" aria-setsize="3" aria-posinset="2" aria-selected="true"><span class="text">Kauf</span></a></li><li><a role="option" class="dropdown-item" id="bs-select-4-2" tabindex="0"><span class="text">Verkauf</span></a></li></ul></div></div></div>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="col-xs-6">
                                        <span class="settings-label">Stück</span>
                                    </div>
                                    <div class="col-xs-6">
                                        <input class="js-order-amount trading-amount trading-price-field textbox pull-left" type="text" maxlength="9" required="required" placeholder="Menge" value="1" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="" data-original-title="Wie viele Stück möchten Sie kaufen?">
                                    </div>
                                </div>
                                <div class="row js-stop-order-row" style="display: none">
                                    <div class="col-xs-6">
                                        <span class="settings-label"><span class="trade-popup-stop-price-text">Stop-Limit</span></span>
                                    </div>
                                    <div class="col-xs-6">
                                        <input class="js-trade-popup-stop-price js-trading-decimal-field trading-price-field textbox" maxlength="15" type="text" value="" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                    </div>
                                </div>
                                <div class="row js-limit-or-stop-order-row" style="display: none">
                                    <div class="col-xs-6">
                                        <span class="settings-label">Limit</span>
                                    </div>
                                    <div class="col-xs-6">
                                        <input class="js-trade-popup-limit-price js-trading-decimal-field trading-price-field textbox" type="text" maxlength="15" value="" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                    </div>
                                </div>
                                <div class="row js-limit-or-stop-order-row" style="display: none">
                                    <div class="col-xs-6">
                                        <span class="settings-label limit-trade-valid-until-text hidden-xs">Gültig bis (Tagesende)</span>
                                        <span class="settings-label limit-trade-valid-until-text hidden-sm hidden-md hidden-lg">Gültig bis</span>
                                    </div>
                                    <div class="col-xs-6">
                                        <div class="js-datepicker-valid-until">
                                            <span class="textbox-icon-left textbox-icon-clickable js-valid-until-icon">
                                                <i class="icon-calendar2"></i>
                                            </span>
                                            <input class="limit-order-valid-until-date js-limit-order-valid-until textbox" type="text" maxlength="10" value="23.10.2021" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>Ihre Order läuft zum gewählten Tag, um 23:59 Uhr automatisch ab.</div>">
                                        </div>
                                    </div>
                                </div>
                                    <div class="trade-popup-tpsl-xs-border u-mt-3" style="display: none">
                                        <div class="row js-trade-popup-tp-row" style="display: none">
                                            <div class="col-xs-12">
                                                <div class="trading-dialog-tpsl-row checkbox" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                                    <input id="modal-dialog-take-profit-checkbox" type="checkbox" class="trade-popup-take-profit-checkbox">
                                                    <label for="modal-dialog-take-profit-checkbox" class="trading-dialog-take-profit-label">Take Profit platzieren</label>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="js-trade-popup-cell-tp-active js-trade-popup-cell-tp-deleted-container" style="display: none">
                                            <div class="row js-trade-popup-tp-row" style="display: none;">
                                                <div class="col-xs-6">
                                                    <span class="settings-label">
                                                        <span class="js-trade-popup-cell-tp-active" style="display: none;">
                                                            <span class="limit-trade-amount-sum-text">Limit</span>
                                                        </span>
                                                        <span class="trade-popup-cell-tp-inactive js-trade-popup-cell-tp-deleted" style="display: none;"></span>
                                                    </span>
                                                </div>
                                                <div class="col-xs-6 js-trade-popup-cell-tp-active" style="display: none;">
                                                    <input class="inline js-take-profit-limit-price js-trading-decimal-field trading-price-field textbox" maxlength="15" type="text" value="" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>Z***</div>">
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="trade-popup-tpsl-xs-border u-mt-2" style="display: none;">
                                        <div class="row js-trade-popup-sl-row js-trade-popup-sl-row-first" style="display: none">
                                            <div class="col-xs-12">
                                                <div class="trading-dialog-tpsl-row checkbox" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                                    <input id="modal-dialog-stop-loss-checkbox" type="checkbox" class="trade-popup-stop-loss-checkbox">
                                                    <label for="modal-dialog-stop-loss-checkbox" class="trading-dialog-stop-loss-label">Stop-Loss platzieren</label>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="js-trade-popup-cell-sl-active js-trade-popup-cell-sl-deleted-container" style="display: none">
                                            <div class="row js-trade-popup-sl-row trade-popup-sl-row js-trade-popup-sl-row-first" style="display: none;">
                                                <div class="col-xs-6">
                                                    <span class="settings-label">
                                                        <span style="display: none;" class="js-trade-popup-cell-sl-active">Stop-Limit</span>
                                                        <span class="js-trade-popup-cell-sl-inactive js-trade-popup-cell-sl-deleted" style="display: none;"></span>
                                                    </span>
                                                </div>
                                                <div class="col-xs-6 js-trade-popup-cell-sl-active" style="display: none;">
                                                    <input class="inline js-trade-popup-sl-stop-price js-trading-decimal-field trading-price-field textbox" maxlength="15" type="text" value="" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                                </div>
                                            </div>
                                            <div class="row js-trade-popup-row-sl-active js-trade-popup-sl-row js-trade-popup-sl-row-second" style="display: none;">
                                                <div class="col-xs-6">
                                                    <span class="settings-label">
                                                        <span style="display: none;" class="js-trade-popup-cell-sl-active">Limit</span>
                                                        <span class="js-trade-popup-cell-sl-inactive"></span>
                                                    </span>
                                                </div>
                                                <div class="col-xs-6 js-trade-popup-cell-sl-active" style="display: none;">
                                                    <input class="inline js-trade-popup-sl-limit-price js-trading-decimal-field trading-price-field textbox" maxlength="15" type="text" value="" data-toggle="tooltip" data-html="true" data-trigger="manual" data-container="body" data-placement="right" title="<div class=' wikifolio-tooltip-icon'></div>
                <div class='wikifolio-tooltip-text'>***</div>">
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                <div class="trading-panel-notice trading-panel-notice-tutorial js-tutorial-row text-center visible-xs" style="display: none;">
                                    <div class="js-limit-order-tutorial-row" style="display: none;">
                                       ***
                                        <br>
                                        ***
                                        <a class="area capitalized" href="/de/de/hilfe/tutorials-trader/limit-orders" target="_blank"><span>mehr...</span></a>
                                    </div>
                                    <div class="js-stop-limit-order-tutorial-row" style="display: none;">
                                       ***
                                        <br>
                                        ***
                                        <a class="area capitalized" href="/de/de/hilfe/tutorials-trader/stop-limit-orders" target="_blank"><span>mehr...</span></a>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

.......

现在的问题是:在与输入字段交互之前,我是否需要先处理父元素或祖先元素之一(例如 div)?

我也想知道 HTML 中的这部分是关于什么的:

<div class="authorization-request-panel" style="display: none;">
                    <div class="spinner-modal-wrapper">
                        <div class="spinner"></div>
                    </div>
                </div>

这是直接写在 HTML 中的“modal-dialog”div 之后。

我还在 *** 中检查了多个威胁。所有的解决方案都会导致一个 incorecct XPATH Locator。但是,当我直接将它插入浏览器时,为什么 XPATH 会唯一地指向正确的输入字段,就像在屏幕截图中一样?

谁能帮我解决这个问题?

非常感谢,我很感激, 本杰明

【问题讨论】:

【参考方案1】:
    Xpath 本质上是脆弱的,尽量使用relative xpath 而不是absolute xpath。 请务必在需要时使用element_to_be_clickable。 需要先清空输入框,然后send_keys 使用explicit waits。 以全屏模式启动浏览器。 首选是css selector,最不首选的选择是xpath

代码:

driver = webdriver.Chrome(driver_path)
#driver.maximize_window()
driver.implicitly_wait(30)
wait = WebDriverWait(driver, 30)
driver.get("https://www.wikifolio.com/dynamic/de/de/login/login?ReturnUrl=/de/de/home&_=1632037782306")

wait.until(EC.element_to_be_clickable((By.NAME, "Username"))).send_keys('******')
wait.until(EC.element_to_be_clickable((By.ID, "Password"))).send_keys('******')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.gtm-login"))).click()

driver.get("https://www.wikifolio.com/de/de/meine-wikifolios/trade/wf00wiking")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.js-disclaimer__change"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[@data-description='AKER CARB.CAPT.AS NK1']"))).click()
select1  = Select(driver.find_element_by_css_selector("div.dropdown>select.order-type-selector"))
select1.select_by_value('quote')

#to select purchase or sale action:
select2 = Select(driver.find_element_by_css_selector("div.dropdown>select.order-buysell-selector"))
# select by value "buy"
select2.select_by_value('buy')

buttonnew = wait.until(EC.element_to_be_clickable((By.XPATH, "(//input[contains(@class,'trading-amount')])[2]")))
buttonnew.clear()
buttonnew.send_keys("22")

【讨论】:

【参考方案2】:

不,没有必要在与输入字段交互之前寻址父元素或祖先元素之一(除非该元素位于框架集的框架内)。您能否将“22”作为字符串而不是整数传递?

# passing "22" as a string
newaction.move_to_element(buttonnew).send_keys(str(22)).perform() 

【讨论】:

以上是关于Selenium:正确的定位器,但不能与元素交互(输入字段)的主要内容,如果未能解决你的问题,请参考以下文章

selenium+Python元素定位

web自动化:selenium原理和元素定位

Python-selenium 元素定位

Selenium2学习-- 八种元素元素定位(Firebug和firepath)

selenium ,web控件定位,常见操作,控件交互进阶

selenium使用Xpath定位之完整篇