在Selenium中,无法点击通过点击某个按钮显示的菜单中的按钮

编程语言 2026-07-08

我在用Selenium自动点击一个菜单,这样就能抓取一些价格。下面是我的一段代码:

import sched, time
from selenium import webdriver
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

def petjunior(driver):

 driver.implicitly_wait(15)
 petages = driver.find_element(By.CLASS_NAME, "_container_1dlh7_1._size__xl_1dlh7_72")
 petmenu = petages.find_element(By.XPATH, '//*[@title="Select age"]').click()
 time.sleep(2)
 junclick = petmenu.find_element(By.XPATH, '//*[text()="Junior"]').click() 
 time.sleep(5)


options = Options()
options.add_argument('--window-size=1296,1115')
options.add_argument("--lang=en-US")
driver = webdriver.Chrome(options=options)
driver.get("https://starpets.gg/adopt-me/shop/pet/hot_doggo/17996")
driver.implicitly_wait(5)
cookiedecl = driver.find_element(By.CLASS_NAME, "cookie__button._button_1fum3_1._button__secondary_1fum3_413._button_mm_1fum3_134._button_fullWidth_1fum3_268._button__text_upper_1fum3_73._button__text_ellipsis_1fum3_76.cookie__button").click()
time.sleep(5)

petjunior(driver)
# A piece of code that I'll be using as example, since this kind of code is repeated several times in my program for all the different buttons and pages

然而,我似乎无法在点击按钮“All”后让它识别菜单,这个按钮是通过以下操作得到的:

petages = driver.find_element(By.CLASS_NAME, "_container_1dlh7_1._size__xl_1dlh7_72")
petmenu = petages.find_element(By.XPATH, '//*[@title="Select age"]').click()

当尝试点击任意按钮,在这个例子中是junior,使用: junclick = petmenu.find_element(By.XPATH, '//*[text()="Junior"]').click(),我得到以下回溯信息和错误:

Traceback (most recent call last):
  File "c:\Users\OneDrive\Desktop\testing\test.py", line 25, in <module>
    petjunior(driver)
    ~~~~~~~~~^^^^^^^^
  File "c:\Users\OneDrive\Desktop\testing\test.py", line 12, in petjunior
    junclick = petmenu.find_element(By.XPATH, '//*[text()="Junior"]').click()
               ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'find_element'

如果把petmenu换成driver,如下所示: junclick = driver.find_element(By.XPATH, '//*[text()="Junior"]').click(),它会点击页面上同名的按钮,这会导致页面跳转到一个带有我需要信息的不同链接,而不是简单地把信息加载到预先存在的页面上。通常这没问题,但我需要程序在多个页面上点击所有年龄段,这导致大约一分钟后出现ERR_CONNECTION_TIMED_OUT,尽管我在所有线程中加入time.sleep() 的间隔(各自之间大约10-60秒),只有在重置我的WiFi之后才能访问该网站。

我也尝试让它去寻找下拉菜单中所有按钮的容器,并尝试从那里执行按钮的点击,但得到的结果与上述两种情况类似。

有没有办法阻止它点击不在菜单中的按钮,或在它点击会跳转到不同链接的按钮时防止ERR_CONNECTION_TIMED_OUT?

解决方案

  • implicitly_wait(n) 对动态应用来说已不再那么有效。相反,你需要使用 WebDriverWait

  • The classname attribute values like _button_1fum3_1, _button__secondary_1fum3_413 are dynamically generated and is bound to change sooner/later. They may change next time you access the application afresh or even while next application startup. So those aren't reliable be used in locators.

  • While webscrapping you should always ACCEPT cookies notification rather declining them.

  • click() doesn't returns anything, so none is assigned back to cookiedecl

  • Your optimized minimal working code to select Junior is as follows:

``` from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time

def petjunior(driver): WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Select age']"))).click() WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[@role='listitem']//div[normalize-space()='Junior']"))).click() time.sleep(5) # time to observe Junior being selected

# -- main -- Usage options = Options() options.add_argument("start-maximized") driver = webdriver.Chrome(options=options) driver.get("https://starpets.gg/adopt-me/shop/pet/hot_doggo/17996") WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='cookies-notification']//button[contains(@class, 'cookie__button')]//div[contains(., 'Accept')]"))).click() time.sleep(5) petjunior(driver) ```


To click and select each of the list items Newborn, Junior, Pre-Teen, Teen, Post-Teen and Full-Grown one after another your optimized minimal working code is as follows:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def petjunior(driver, age_range):
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Select age']"))).click()
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, f"//div[@role='listitem']//div[normalize-space()='{age_range}']"))).click()


# -- main -- Usage
options = Options()
options.add_argument("start-maximized")
driver = webdriver.Chrome(options=options)
driver.get("https://starpets.gg/adopt-me/shop/pet/hot_doggo/17996")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='cookies-notification']//button[contains(@class, 'cookie__button')]//div[contains(., 'Accept')]"))).click()
time.sleep(5)
petjunior(driver, "Newborn")
time.sleep(5) //time span to observe Newborn being selected
petjunior(driver, "Junior")
time.sleep(5) //time span to observe Junior being selected
petjunior(driver, "Pre-Teen")
time.sleep(5) //time span to observe Pre-Teen being selected
petjunior(driver, "Teen")
time.sleep(5) //time span to observe Teen being selected
petjunior(driver, "Post-Teen")
time.sleep(5) //time span to observe Post-Teen being selected
petjunior(driver, "Full-Grown")
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章