如何使用Watir点击所有带特定class名的div元素
Watir 批量点击同类div唤起弹窗抓取数据实现方案
首先明确核心逻辑:页面中无跳转链接、仅靠点击同class div唤起弹窗的场景,核心要解决同class元素批量定位、DOM变动导致的元素失效两个核心问题,具体实现步骤如下:
- 前置准备:初始化浏览器并等待目标元素加载完成
不要在元素还没渲染完的时候就去取元素集合,很容易拿不全目标div,参考代码:require 'watir' # 启动Chrome浏览器,需要无头模式可以把headless参数改成true browser = Watir::Browser.new :chrome browser.goto '替换为你要抓取的目标页面地址' # 等待所有带目标class的div加载完成,把target-div-class替换为实际的div类名 target_div_class = 'target-div-class' browser.divs(class: target_div_class).wait_until(&:exists?) - 遍历点击逻辑:按索引循环定位,避免元素引用失效
很多新手会直接把找到的所有div存成数组遍历,这种写法只要点击弹窗、关闭弹窗的操作触发页面DOM重绘,之前存的元素引用就会失效,报「元素不存在」的错误,最稳定的写法是每次循环按索引重新定位元素:# 先获取目标div的总数量 div_count = browser.divs(class: target_div_class).count # 初始化数组存抓取结果 crawl_result = [] div_count.times do |index| begin # 每次循环重新定位当前序号的div current_trigger = browser.div(class: target_div_class, index: index) # 滚动到元素位置,避免元素不在视口被遮挡导致点击失败 current_trigger.scroll.to current_trigger.click # 等待弹窗加载,把popup-wrapper替换为实际弹窗的外层容器class popup = browser.div(class: 'popup-wrapper') popup.wait_until(&:present?) # 这里写你的弹窗数据抓取逻辑,示例: # data = { # title: popup.h3.text, # content: popup.div(class: 'popup-content').text # } # crawl_result << data # 抓取完成后关闭弹窗,把close-btn替换为实际关闭按钮的定位属性 browser.button(class: 'close-btn').click # 等弹窗完全消失再进入下一轮循环,避免遮挡后续点击 popup.wait_while(&:present?) rescue Watir::Exception => e puts "第#{index + 1}个div操作异常,已跳过:#{e.message}" # 兜底操作:如果弹窗卡住没关,按ESC键强制关闭 browser.send_keys :escape next end end # 所有数据抓取完成后可以按需导出结果、关闭浏览器 browser.close - 优化注意事项
- 不要用固定时长的
sleep做等待,优先用Watir自带的wait_until/wait_while判断元素实际状态,脚本稳定性更高、运行速度更快 - 如果部分div有特殊状态(比如置灰不可点击),可以在点击前加判断
next unless current_trigger.present? && current_trigger.enabled?跳过不可操作的元素 - 如果同class的div里混了非触发弹窗的元素,可以在定位时加额外过滤条件,比如加文本匹配、自定义data属性匹配,缩小定位范围
- 不要用固定时长的
内容的提问来源于stack exchange,提问作者Kay
相关产品推荐
相关产品推荐

