点击下拉选项,获取带有空消息的基本WebDriver异常。

huangapple go评论56阅读模式
英文:

Clicking dropdown option, getting base WebDriverException with empty Message

问题

使用Python和Selenium在Safari浏览器中,尝试选择下拉框中的选项。

下拉框在HTML中如下所示:

<select name="ctl00$cph1$d1$cboExchange" onchange="javascript:setTimeout('__doPostBack(\'ctl00$cph1$d1$cboExchange\',\'\')', 0)" id="ctl00_cph1_d1_cboExchange" style="width:205px;margin-left:30px;">
    <option value="AMEX">American Stock Exchange</option>
    <option value="ASX">Australian Securities Exchange</option>
    <option value="CFE">Chicago Futures Exchange</option>
    <option value="EUREX">EUREX Futures Exchange</option>
    <option value="FOREX">Foreign Exchange</option>
    <option selected="selected" value="INDEX">Global Indices</option>
    <option value="HKEX">Hong Kong Stock Exchange</option>
    <option value="KCBT">Kansas City Board of Trade</option>
    <option value="LIFFE">LIFFE Futures and Options</option>
    <option value="LSE">London Stock Exchange</option>
    <option value="MGEX">Minneapolis Grain Exchange</option>
    <option value="USMF">Mutual Funds</option>
    <option value="NASDAQ">NASDAQ Stock Exchange</option>
    <option value="NYBOT">New York Board of Trade</option>
    <option value="NYSE">New York Stock Exchange</option>
    <option value="OTCBB">OTC Bulletin Board</option>
    <option value="SGX">Singapore Stock Exchange</option>
    <option value="TSX">Toronto Stock Exchange</option>
    <option value="TSXV">Toronto Venture Exchange</option>
    <option value="WCE">Winnipeg Commodity Exchange</option>
</select>

您的选择相关代码如下:

try:
    exchange_dropdown_id = 'ctl00_cph1_d1_cboExchange'

    exchange_dropdown = driver.find_element(by=By.ID, value=exchange_dropdown_id)
    exchange_dropdown_select = Select(exchange_dropdown)

    print('-- 点击下拉元素')
    exchange_dropdown_select.select_by_value('AMEX')

    print('成功!')

except (selenium.common.exceptions.ElementClickInterceptedException,
        selenium.common.exceptions.ElementNotInteractableException,
        selenium.common.exceptions.ElementNotSelectableException,
        selenium.common.exceptions.ElementNotVisibleException,
        selenium.common.exceptions.ImeActivationFailedException,
        selenium.common.exceptions.ImeNotAvailableException,
        selenium.common.exceptions.InsecureCertificateException,
        selenium.common.exceptions.InvalidCookieDomainException,
        selenium.common.exceptions.InvalidCoordinatesException,
        selenium.common.exceptions.InvalidElementStateException,
        selenium.common.exceptions.InvalidSelectorException,
        selenium.common.exceptions.InvalidSessionIdException,
        selenium.common.exceptions.InvalidSwitchToTargetException,
        selenium.common.exceptions.JavascriptException,
        selenium.common.exceptions.MoveTargetOutOfBoundsException,
        selenium.common.exceptions.NoAlertPresentException,
        selenium.common.exceptions.NoSuchAttributeException,
        selenium.common.exceptions.NoSuchCookieException,
        selenium.common.exceptions.NoSuchElementException,
        selenium.common.exceptions.NoSuchFrameException,
        selenium.common.exceptions.NoSuchShadowRootException,
        selenium.common.exceptions.NoSuchWindowException,
        selenium.common.exceptions.ScreenshotException,
        selenium.common.exceptions.SeleniumManagerException,
        selenium.common.exceptions.SessionNotCreatedException,
        selenium.common.exceptions.StaleElementReferenceException,
        selenium.common.exceptions.TimeoutException,
        selenium.common.exceptions.UnableToSetCookieException,
        selenium.common.exceptions.UnexpectedAlertPresentException,
        selenium.common.exceptions.UnexpectedTagNameException,
        selenium.common.exceptions.UnknownMethodException,
        ) as ex:
    print('*** 可能出现异常:\n' + repr(ex) + '\n*** 结束异常详情')

except selenium.common.exceptions.WebDriverException as ex:
    print('*** WebDriver基本异常:\n' + repr(ex) + '\n*** 结束基本异常详情')

except Exception as ex:
    print('*** 选择项目失败。异常:\n' + str(ex) + '*** 结束异常消息 ***')
    print('*** 异常详情:\n' + repr(ex) + '\n*** 结束异常消息 ***')

结果是:

-- 点击下拉元素
*** WebDriver基本异常:
WebDriverException()
*** 结束基本异常详情

如果我使用str(ex)而不是repr(ex),我会得到只有"MESSAGE:"字样的输出。

我已经将WebDriver API中的所有异常都列出,希望能捕获到告诉我发生了什么的异常。

我已经尝试使用select_by_visible_text('American Stock Exchange'),结果也相同。

您可以通过Select对象迭代所有选项:

for option in exchange_dropdown_select.options:
    print(option.get_attribute('value'))
    if option.get_attribute('value') == 'AMEX':
        print('找到AMEX')

如果我添加了对选项的点击:

for option in exchange_dropdown_select.options:
    print(option.get_attribute('value'))
    if option.get_attribute('value') == 'AMEX':
        print('找到AMEX')
        option.click()
        print('点击AMEX')

仍然会以空的WebDriver异常结束。

问题可能与表格包围的HTML有关,我正在使用Python 3.9。

任何关于可能发生的情况以及如何修复的想法?

另外,我宁愿不使用XPATH或索引值,因为开发人员可能更改选项的顺序,而XPATH没有包含与我要选择的项相关的ID信息 - 再次强调,如果选项顺序发生变化,这个路径也可能会改变。

此外,我的导入如下:

import sys

import selenium # 用于下面的所有异常;在解决后将被删除
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait

更新:要解决这个问题,请执行以下步骤:

  • 从URL eoddata.com开始。
  • 登录(免费帐户即可)。
  • 点击左上角的“下载”按钮。
  • 单击关闭弹出窗口的“X”按钮。

然后,我正在查看左上角的“下载数据”部分。

在这个特定的示例中,我想选择交易所 - value = "AMEX"visible text = "American Stock Exchange"。它目前是第一个索引,但再次强调,这可能随时更改,因此我不想依赖于精确位置。

最后,在尊重网民的情况下

英文:

Using Python & Selenium in Safari browser; trying to select from a dropdown box.

The dropdown looks like this in the HTML:

&lt;select name=&quot;ctl00$cph1$d1$cboExchange&quot; onchange=&quot;javascript:setTimeout(&#39;__doPostBack(\&#39;ctl00$cph1$d1$cboExchange\&#39;,\&#39;\&#39;)&#39;, 0)&quot; id=&quot;ctl00_cph1_d1_cboExchange&quot; style=&quot;width:205px;margin-left:30px;&quot;&gt;
				&lt;option value=&quot;AMEX&quot;&gt;American Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;ASX&quot;&gt;Australian Securities Exchange&lt;/option&gt;
				&lt;option value=&quot;CFE&quot;&gt;Chicago Futures Exchange&lt;/option&gt;
				&lt;option value=&quot;EUREX&quot;&gt;EUREX Futures Exchange&lt;/option&gt;
				&lt;option value=&quot;FOREX&quot;&gt;Foreign Exchange&lt;/option&gt;
				&lt;option selected=&quot;selected&quot; value=&quot;INDEX&quot;&gt;Global Indices&lt;/option&gt;
				&lt;option value=&quot;HKEX&quot;&gt;Hong Kong Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;KCBT&quot;&gt;Kansas City Board of Trade&lt;/option&gt;
				&lt;option value=&quot;LIFFE&quot;&gt;LIFFE Futures and Options&lt;/option&gt;
				&lt;option value=&quot;LSE&quot;&gt;London Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;MGEX&quot;&gt;Minneapolis Grain Exchange&lt;/option&gt;
				&lt;option value=&quot;USMF&quot;&gt;Mutual Funds&lt;/option&gt;
				&lt;option value=&quot;NASDAQ&quot;&gt;NASDAQ Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;NYBOT&quot;&gt;New York Board of Trade&lt;/option&gt;
				&lt;option value=&quot;NYSE&quot;&gt;New York Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;OTCBB&quot;&gt;OTC Bulletin Board&lt;/option&gt;
				&lt;option value=&quot;SGX&quot;&gt;Singapore Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;TSX&quot;&gt;Toronto Stock Exchange&lt;/option&gt;
				&lt;option value=&quot;TSXV&quot;&gt;Toronto Venture Exchange&lt;/option&gt;
				&lt;option value=&quot;WCE&quot;&gt;Winnipeg Commodity Exchange&lt;/option&gt;

			&lt;/select&gt;

My select-related code looks like this:

    try:
        exchange_dropdown_id = &#39;ctl00_cph1_d1_cboExchange&#39;

        exchange_dropdown = driver.find_element(by=By.ID, value=exchange_dropdown_id)
        exchange_dropdown_select = Select(exchange_dropdown)

        print(&#39;-- clicking dropdown element&#39;)
        exchange_dropdown_select.select_by_value(&#39;AMEX&#39;)

        print(&#39;IT WORKED!&#39;)

    except (selenium.common.exceptions.ElementClickInterceptedException,
            selenium.common.exceptions.ElementNotInteractableException,
            selenium.common.exceptions.ElementNotSelectableException,
            selenium.common.exceptions.ElementNotVisibleException,
            selenium.common.exceptions.ImeActivationFailedException,
            selenium.common.exceptions.ImeNotAvailableException,
            selenium.common.exceptions.InsecureCertificateException,
            selenium.common.exceptions.InvalidCookieDomainException,
            selenium.common.exceptions.InvalidCoordinatesException,
            selenium.common.exceptions.InvalidElementStateException,
            selenium.common.exceptions.InvalidSelectorException,
            selenium.common.exceptions.InvalidSessionIdException,
            selenium.common.exceptions.InvalidSwitchToTargetException,
            selenium.common.exceptions.JavascriptException,
            selenium.common.exceptions.MoveTargetOutOfBoundsException,
            selenium.common.exceptions.NoAlertPresentException,
            selenium.common.exceptions.NoSuchAttributeException,
            selenium.common.exceptions.NoSuchCookieException,
            selenium.common.exceptions.NoSuchElementException,
            selenium.common.exceptions.NoSuchFrameException,
            selenium.common.exceptions.NoSuchShadowRootException,
            selenium.common.exceptions.NoSuchWindowException,
            selenium.common.exceptions.ScreenshotException,
            selenium.common.exceptions.SeleniumManagerException,
            selenium.common.exceptions.SessionNotCreatedException,
            selenium.common.exceptions.StaleElementReferenceException,
            selenium.common.exceptions.TimeoutException,
            selenium.common.exceptions.UnableToSetCookieException,
            selenium.common.exceptions.UnexpectedAlertPresentException,
            selenium.common.exceptions.UnexpectedTagNameException,
            selenium.common.exceptions.UnknownMethodException,
            ) as ex:
        print(&#39;*** POSSIBLE EXCEPTION FOUND:\n&#39; + repr(ex) + &#39;\n*** END REPR&#39;)

    except selenium.common.exceptions.WebDriverException as ex:
        print(&#39;*** WEBDRIVER BASE EXCEPTION:\n&#39; + repr(ex) + &#39;\n*** END BASE EXCEPTION DETAIL&#39;)

    except Exception as ex:
        print(&#39;*** Failure selecting item. Exception:\n&#39; + str(ex) + &#39;*** END EXCEPTION MESSAGE ***&#39;)
        print(&#39;*** Exception Detail?:\n&#39; + repr(ex) + &#39;\n*** END EXCEPTION MESSAGE ***&#39;)

The result is:

> -- clicking dropdown element
> *** WEBDRIVER BASE EXCEPTION:
> WebDriverException()
> *** END BASE EXCEPTION DETAIL

If I use str(ex) instead of repr(ex), I get the word MESSAGE: with no other information.

I entered all the exceptions in the WebDriver API in hopes of catching "the one" that would tell me what's happening.

I have tried using select_by_visible_text(&#39;American Stock Exchange&#39;) as well, with the same result.

I can iterate through all the options with the Select object:

        for option in exchange_dropdown_select.options:
            print(option.get_attribute(&#39;value&#39;))
            if option.get_attribute(&#39;value&#39;) == &#39;AMEX&#39;:
                print(&#39;AMEX found&#39;)

and it finds the option. However, if I add a click on the option:

        for option in exchange_dropdown_select.options:
            print(option.get_attribute(&#39;value&#39;))
            if option.get_attribute(&#39;value&#39;) == &#39;AMEX&#39;:
                print(&#39;AMEX found&#39;)
                option.click()
                print(&#39;clicked AMEX&#39;)

it still ends with the empty WebDriver exception:

> AMEX found
> *** WEBDRIVER BASE EXCEPTION:
> WebDriverException()
> *** END BASE EXCEPTION DETAIL.

The HTML is enclosed in a table, if that makes a difference. And, I'm using Python 3.9.

Any ideas what might be happening and how I might fix it?

Also, I'd prefer not to use the XPATH or index values as the developers might change the order of the options, and the XPATH doesn't contain any ID information relating to the item(s) I want to select - again, a path that could change if the option order changes.

Oh, and my imports are:

import sys

import selenium # for all of those exceptions down there; will be removed when solved
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait

Update: to get to the issue -

  • start with the URL eoddata.com
  • log in (free account is fine)
  • click the Download button at the upper left (next to Home Page button)
  • click the 'X' to close the popup

Then, I'm looking at the Download Data portion in the upper left.

In this particular example, I want to select the Exchange - value = &quot;AMEX&quot; and visible text = &quot;American Stock Exchange&quot;. It's currently the first index, but again, this could change at any time, so I don't want to count on an exact position, if I can help it.

Finally, in respectful netizenship, the current robots.txt is:

User-agent: *
Crawl-delay:10
Disallow: /images/
Disallow: /styles/
Disallow: /scripts/
User-agent: turnitinbot 
Disallow: /
Sitemap: http://www.eoddata.com/sitemapindex.xml

Update 2:
Apple Docs related to safaridriver (accessed 28 Feb 2023):

I have found a number of posts, without selected answers, asking about this issue in Safari. I've not found any instructional info with a SELECT specifically - and all of the rest of the steps I listed above are working perfectly.

It looks like I need a REST way of accessing the SELECT/OPTION item -- or, I need to switch to Firefox or Chrome, lol.

答案1

得分: 0

以下是翻译好的部分:

from selenium.webdriver.support.ui import Select
exchange_dropdown = driver.find_element(By.ID, 'ctl00_cph1_d1_cboExchange')
Select(exchange_dropdown).select_by_value('AMEX')

Alternative (1)

exchange_dropdown = driver.find_element(By.ID, 'ctl00_cph1_d1_cboExchange')
option = exchange_dropdown.find_element(By.CSS_SELECTOR, 'option[value=AMEX]')
exchange_dropdown.send_keys(option.text)

Alternative (2)

exchange_dropdown = driver.find_element(By.ID, 'ctl00_cph1_d1_cboExchange')
option = exchange_dropdown.find_element(By.CSS_SELECTOR, 'option[value=AMEX]')
option.click()
英文:

To me this works without problems using chromedriver

from selenium.webdriver.support.ui import Select
exchange_dropdown = driver.find_element(By.ID, &#39;ctl00_cph1_d1_cboExchange&#39;)
Select(exchange_dropdown).select_by_value(&#39;AMEX&#39;)

Alternative (1)

exchange_dropdown = driver.find_element(By.ID, &#39;ctl00_cph1_d1_cboExchange&#39;)
option = exchange_dropdown.find_element(By.CSS_SELECTOR, &#39;option[value=AMEX]&#39;)
exchange_dropdown.send_keys(option.text)

Alternative (2)

exchange_dropdown = driver.find_element(By.ID, &#39;ctl00_cph1_d1_cboExchange&#39;)
option = exchange_dropdown.find_element(By.CSS_SELECTOR, &#39;option[value=AMEX]&#39;)
option.click()

huangapple
  • 本文由 发表于 2023年2月24日 07:53:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定