跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Python爬虫怎么处理多级菜单_通过模拟鼠标悬停触发菜单加载

菜单未加载是因HTTP客户端无法触发mouseover事件,需用Selenium/Playwright模拟真实浏览器交互,配合显式等待、滚动定位、可见性校验及上下文复用。 菜单没加载出来,是因为没触发
mouseover
事件 浏览器里鼠标悬停(
mouseover
)才拉取子菜单数据,但 Requests 这类纯 HTTP 客户端根本不会发这个事件,也没 DOM 树可“悬停”。直接请求页面 HTML,
ul
里空空如也,不是你 selector 写错,是压根没加载。 实操建议: 立即学习 “ Python免费学习笔记(深入) ”; 用
Selenium
或
Playwright
启动真实浏览器环境,才能模拟真实交互 别依赖
time.sleep()
等固定时间,改用显式等待:
WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".submenu")))
悬停后要等子菜单 DOM 出现、且
display: block
或
visibility: visible
生效,否则可能拿到空节点
ActionChains
的
move_to_element
不生效?检查元素是否在视口内 如果目标菜单项在滚动区域外(比如二级导航藏在顶部 fixed bar 下方),
move_to_element
会静默失败——它不自动滚动,也不报错。 实操建议: 立即学习 “ Python免费学习笔记(深入) ”; 先用
driver.execute_script("arguments[0].scrollIntoView(true);", menu_item)
把元素滚进可视区 再执行
ActionChains(driver).move_to_element(menu_item).perform()
验证是否成功:悬停后立刻查
menu_item.find_element(By.CLASS_NAME, "submenu").get_attribute("class")
,看有没有
show
或
open
类名 用
Playwright
更稳,但要注意
hover
的默认超时和重试逻辑
Playwright
的
page.hover(selector)
默认带 5 秒超时 + 自动重试,看似省心,但容易掩盖问题:比如 selector 匹配到多个元素,它会 hover 第一个(未必是你想要的);或者元素被遮挡,hover 失败却因重试而延迟返回。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 实操建议: 立即学习 “ Python免费学习笔记(深入) ”; 加明确的定位约束:
page.locator("nav > ul > li:has-text('产品')").hover()
,避免模糊匹配 禁用自动重试,自己控制流程:
await page.locator(selector).hover({ timeout: 3000 })
hover 后立刻用
locator(".submenu").is_visible()
断言,比单纯等时间更可靠 爬完多级菜单后,别直接关浏览器——小心连接复用失效 很多网站菜单接口是带 session 或 token 的,靠浏览器上下文维持。如果你 hover 拿到子菜单 URL 后,切回
Requests
去请求,大概率 403 或空响应,因为没传 cookie、没带 referer、没复用 WebSocket 连接。 实操建议: 立即学习 “ Python免费学习笔记(深入) ”; 整个链路保持在同一个
Page
实例里完成:hover → 获取子菜单链接 →
page.goto(submenu_url)
如果必须切 Requests,至少导出当前页的
cookies
和
headers
(尤其是
Referer
和
User-Agent
) 注意部分菜单是 fetch 加载的 JSON,得监听
page.on("response", ...)
捕获 XHR,而不是只看 HTML 结构 多级菜单的“悬停”本质是状态机:触发 → 渲染 → 可见 → 可交互。漏掉任一环,拿到的都是假数据。最常被忽略的是“可见性判断”——DOM 存在 ≠ 菜单已展开,得查样式或类名,不能只靠
find_element
不报错就认为成功。

相关文章