无法在Python应用程序中选择下拉菜单

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在Python应用程序中选择下拉菜单相关的知识,希望对你有一定的参考价值。

enter image description here

我有一个脚本,可从网站上抓取值,并具有一个下拉悬停菜单,需要将父菜单悬停在该菜单上,并选择了一个下拉选项。直到几天前,它一直运行良好。但是现在随机失败。

这是我当前的代码:

def select_dropdown():

    WebDriverWait(driver, 10).until(ec.visibility_of_element_located(
        (By.CSS_SELECTOR, "div.menu.menuTopCenter > ul > li:nth-child(3) > a")))
    investment = WebDriverWait(driver, 10).until(ec.element_to_be_clickable(
        (By.CSS_SELECTOR, "div.menu.menuTopCenter > ul > li:nth-child(3) > a")))
    actions.move_to_element(investment).perform()
    WebDriverWait(driver, 10).until(
         ec.element_to_be_clickable((By.CSS_SELECTOR, "li:nth-child(3) > div > div:nth-child(1) > a"))).click()

请参见下面的HTML以获得父菜单:

 <a class="menuLink mainMenuItem" href="#" renderstyle="NONE" action="" 
 controller="" clientmodulesubid="0" renderlocation="" 
 clearcontentheader="False" 
 lobsystemuserids="Ls6EVzOdmMPVcdHshYcUbg==">Investment</a>

请参见下面的HTML以了解要选择的选项(sub_menu):

 <a class="menuLink mainMenuItem" href="#" renderstyle="REPLACE" action="Index" 
 controller="Portfolio" clientmodulesubid="6109" 
 renderlocation="contentHeaderContainer" clearcontentheader="True" 
 lobsystemuserids="Ls6EVzOdmMPVcdHshYcUbg==">Investment summary</a>

这是我得到的错误:

Traceback (most recent call last):
  File "C:/Users/SChogle/PycharmProjects/Web Scraping All Sites (With BDay).py", line 55, in <module>
    select_dropdown()
  File "C:/Users/SChogle/PycharmProjects/Web Scraping All Sites (With BDay).py", line 29, in select_dropdown
    ec.element_to_be_clickable((By.CSS_SELECTOR, "li:nth-child(3) > div > div:nth-child(1) > a"))).click()
  File "C:UsersSChogleAppDataRoamingPythonPython37site-packagesseleniumwebdriversupportwait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

这是父菜单和所有子菜单的完整HTML:

 <li class="has-children">
<a class="menuLink mainMenuItem" href="#" 
 renderstyle="NONE" action="" controller="" clientmodulesubid="0" 
 renderlocation="" clearcontentheader="False" 
 lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Investment</a>

<div class="subMenu"> 
 <div>

<a class="menuLink mainMenuItem" href="#" renderstyle="REPLACE" 
 action="Index" controller="Portfolio" clientmodulesubid="6109" 
 renderlocation="contentHeaderContainer" clearcontentheader="True" 
 lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Investment summary</a>
</div>

<div>
<a class="menuLink mainMenuItem" href="#" renderstyle="REPLACE" 
 action="GetLazyTransactionHistoryByAccountGroup" controller="Transactions" 
 clientmodulesubid="6108" renderlocation="contentHeaderContainer" 
 clearcontentheader="True" 
 lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Transaction history</a>
</div>

<div> 
 <a class="menuLink mainMenuItem" href="#" renderstyle="REPLACE" 
 action="LoadIncomeDistribution" controller="IncomeDistribution" 
 clientmodulesubid="7005" renderlocation="contentHeaderContainer" 
 clearcontentheader="True" lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Income 
 distribution</a>
</div>

<div>
<a class="menuLink mainMenuItem" href="#" 
 renderstyle="REPLACE" action="PortfolioFees" controller="Fees" 
 clientmodulesubid="6159" renderlocation="contentHeaderContainer" 
 clearcontentheader="True" lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Advisor 
 charges</a>
</div>

<div><a class="menuLink mainMenuItem" href="#" 
 renderstyle="REPLACE" action="GetRecurringInstructionsDetail" 
 controller="RecurringInstructions" clientmodulesubid="6158" 
 renderlocation="contentHeaderContainer" clearcontentheader="True" 
 lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Recurring instructions</a>
</div> 

<div>
<a class="menuLink mainMenuItem" href="#" renderstyle="REPLACE" 
 action="GenerateAdHocWebStatement_SAIP" controller="AdHocWebStatement" 
 clientmodulesubid="6121" renderlocation="contentHeaderContainer" 
 clearcontentheader="True" lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Investor 
 statement</a>
</div>

<div>
<a class="menuLink mainMenuItem" href="#" 
 renderstyle="REPLACE" action="GenerateAdHocWebStatement_SAIP" 
 controller="AdHocWebStatement" clientmodulesubid="8939" 
 renderlocation="contentHeaderContainer" clearcontentheader="True" 
 lobsystemuserids="8qWAwlpk6Jdje8MVVaH1Tw==">Tax certificate</a>
</div>
</div> 
 </li>

我认为可能正在发生的事情是脚本正在尝试在页面加载之前找到元素,但是我不确定。正如我所说的,它有时会起作用,而其他时候会失败。

答案

尝试以下select_menu方法:

def select_menu(menu: str = None, submenu: str = None):
    menu_locator = f"//div[contains(@class,'menu')]//a[.='{menu}']"
    submenu_locator = f"{menu_locator}/ancestor::li[1]/div[@class='subMenu']//a[.='{submenu}']"

    wait = WebDriverWait(driver, 20)

    wait.until(lambda d: d.execute_script("return document.readyState === 'complete' && jQuery.active === 0;"))

    menu_element = wait.until(EC.element_to_be_clickable((By.XPATH, menu_locator)))
    actions.move_to_element(menu_element).perform()

    wait.until(EC.visibility_of_element_located((By.XPATH, submenu_locator))).click()

如何调用方法:

select_menu(menu="Investment", submenu="Investment summary")
另一答案

您可以按照以下步骤尝试调试以缩小解决方案范围:1.使用try catch重试相同的代码块:

count=0, max=5;
while(true){    
try{
    //drop down click
    }
    catch(Exception e){
    if(count++==max) throw e;
    }
}
  1. 您也可以尝试重新加载页面,然后执行直到成功。

    driver.navigate()。refresh();

以上是关于无法在Python应用程序中选择下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Selenium 和 Python 的下拉菜单中选择

无法从引导程序的下拉菜单中选择项目

无法从下拉菜单中选择选项

jquery依赖下拉菜单选择

无法在 Select2 下拉菜单中选择项目

selenium下拉菜单无法选择