如何使用Selenium Python抓取可悬停下拉菜单?
解决抓取悬停菜单不显示的问题
你的代码存在几个导致悬停菜单无法被捕获的核心问题,以下是针对性修正方案:
关键问题点及修正逻辑
- 无头模式窗口尺寸异常:默认无头Chrome窗口过小,会触发网站响应式布局,导致菜单无法正常渲染或展开,需显式设置标准窗口大小。
- User-Agent设置失效:原参数里的空格会导致UA配置不生效,且使用Firefox UA可能触发网站浏览器检测,换成Chrome标准UA更稳妥。
- 多余鼠标操作导致菜单收起:
move_by_offset会让鼠标移开菜单区域,导致已展开的下拉菜单自动收起,需移除该操作。 - 等待逻辑不精准:需等待下拉菜单的子元素完全可见,确保菜单已完成渲染再保存源码,避免捕获到未加载完成的内容。
修正后的完整代码
import time import os from selenium import webdriver from selenium.webdriver.chrome.service import Service 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.common.action_chains import ActionChains from webdriver_manager.chrome import ChromeDriverManager url = 'https://www.classcentral.com' options = webdriver.ChromeOptions() options.add_argument('start-maximized') options.add_argument('--no-sandbox') options.add_argument('--headless=new') # 新版无头模式,渲染逻辑更贴近正常浏览器 options.add_argument('--disable-dev-shm-usage') options.add_argument("--enable-javascript") # 修正UA格式,使用Chrome标准标识 options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36') options.add_argument('referer=https://www.classcentral.com/') # 移除参数内的空格 options.add_argument('--window-size=1920,1080') # 显式设置窗口尺寸 driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) driver.get(url) wait = WebDriverWait(driver, 20) achains = ActionChains(driver) # 等待主菜单按钮可交互并触发悬停 wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-name='LARGE_UP_MAIN_NAV_TRIGGER']"))) menu_button = driver.find_element(By.XPATH, "//button[@data-name='LARGE_UP_MAIN_NAV_TRIGGER']") achains.move_to_element(menu_button).perform() # 等待下拉菜单完全展开,直到子链接可见 wait.until(EC.visibility_of_element_located((By.XPATH, "//nav[@class='main-nav-dropdown js-main-nav-dropdown is-open']//a"))) # 滚动页面加载所有内容,增加短延迟确保内容加载完成 scroll_height = driver.execute_script('return document.body.scrollHeight') step = driver.get_window_size()['height'] // 2 for line in range(0, scroll_height, step): driver.execute_script(f'window.scrollTo({line}, {line + step})') time.sleep(0.5) driver.execute_script(f'window.scrollTo({scroll_height}, 0)') # 创建目标目录并保存页面源码 dirname = 'classcentral' if not os.path.exists(dirname): os.makedirs(dirname) # 用Python原生方法创建目录,提升跨平台兼容性 pagetitle = 'index' if url == 'https://www.classcentral.com' else driver.title with open(os.path.join(dirname, f'{pagetitle}.html'), 'w', encoding='utf-8') as ouf: ouf.write(driver.page_source) driver.quit()
额外优化说明
- 使用
--headless=new替代旧版无头模式,减少渲染差异,避免部分动态元素无法加载。 - 保存文件时指定
encoding='utf-8',防止出现中文乱码问题。 - 替换shell命令
!mkdir为Python原生os.makedirs,避免依赖特定运行环境。
内容的提问来源于stack exchange,提问作者user1063088
相关产品推荐
相关产品推荐

