阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用小技巧教你用Selenium获取鼠标指向的元素

31次阅读
没有评论

共计 2498 个字符,预计需要花费 7 分钟才能阅读完成。

有一个同学在 Gne 的群里面咨询如何通过 Selenium 获取当前鼠标指向的元素,在我讲了方法以后,他过了两天又来问:
使用小技巧教你用 Selenium 获取鼠标指向的元素
那么,我今天就来写一篇文章,具体说说应该怎么操作。

这个方法的核心,是借助 JavaScript 的事件 (event) 来获取鼠标所在的元素。然后再把这个元素传递给 Selenium。我们先来第一步,不考虑 Selenium,只使用 JavaScript,如何获取当前鼠标指向的元素呢?

我们首先需要知道在 JavaScript 中的一个事件句柄,叫做 window.onmousemove。默认情况下,它的值是 null:
使用小技巧教你用 Selenium 获取鼠标指向的元素
我们可以把它的值修改成一个函数,这个函数接收一个 event 参数,这样当鼠标在网页上移动的时候,这个函数就会被调用。而 event 参数是一个对象,这个对象有两个属性.clientX 和.clientY,分别表示鼠标相当于网页的横坐标和纵坐标:

function track_mouse(event){
 var x = event.clientX, y = event.clientY
 console.log('当前鼠标所在位置的坐标:x=' +  x + 'y=' + y)
}

运行效果如下图所示:

使用小技巧教你用 Selenium 获取鼠标指向的元素

你执行命令以后,只要在页面上移动鼠标,你就会在控制台看到大量的坐标被打印出来。

接下来,既然你有了当前鼠标所在位置的坐标,那么你只需要根据坐标查询到这个元素是什么就可以了。在 JavaScript 中,有一个函数叫做 document.elementFromPoint,就能实现这个效果:

function track_mouse(event){
 var x = event.clientX, y = event.clientY
 var element = document.elementFromPoint(x, y)
  if (!element) {return // 当前位置没有元素} 
  return element
}

那么,如何把这个参数返回给 Selenium 呢? 其实也非常简单,我们设置一个全局变量 window.hovered_element,然后把当前鼠标对应的元素赋值给它。然后在 Selenium 中,使用.execute_script 获取 window.hovered_element 就可以了。

我们先来看看完整的 JavaScript:

window.hovered_element = null
function track_mouse(event){
 var x = event.clientX, y = event.clientY
 var element = document.elementFromPoint(x, y)
  if (!element) {
      window.hovered_element = null
  return // 当前位置没有元素
 } 
  window.hovered_element = element
}
window.onmousemove = track_mouse

然后我们再来看看 Selenium 中的 Python 代码:

import time
from selenium.webdriver import Chrome

driver = Chrome('./chromedriver')
driver.get('https://www.kingname.info/')

js = '''window.hovered_element = null
function track_mouse(event){
 var x = event.clientX, y = event.clientY
 var element = document.elementFromPoint(x, y)
  if (!element) {
      window.hovered_element = null
  return // 当前位置没有元素
 } 
  window.hovered_element = element
}
window.onmousemove = track_mouse'''

driver.execute_script(js)
while True:
    element = driver.execute_script('return window.hovered_element')
    if element:
        print(f'当前鼠标所在的标签为:{element.tag_name}, 其中的文本内容为:{element.text}')
    time.sleep(1)

运行效果如下图所示:

使用小技巧教你用 Selenium 获取鼠标指向的元素

获取到了当前鼠标所在的元素的标签和标签里面的文字。

到这里,这个同学需要的功能已经完全实现了。

但可能有聪明的同学会发现,他这个需求是有问题的。我们能看到至少有三个问题:

因为 window.onmousemove 太灵敏了,它的采样时间是毫秒级别的,鼠标稍稍移动一点点就会生成一个事件。但是,一个元素的区域是很大的,在一个元素内部移动鼠标,其实根本没有必要更新 window.hovered_element。
在 Selenium 里面,是通过 while True 每 1 秒查询一次 window.hovered_element,虽然我们已经降低了频率,但大家从上面的图中可以看到,还是会获取到很多重复的数据。这是由于有一些元素非常大,我们鼠标如果在上面慢慢移动,时间会超过 1 秒,那么 Selenium 就会重复获取到数据。
由于 window.onmousemove 的采样时间间隔很小,所以我们可以近似把鼠标的移动看做是连续的移动。因此,这段代码会记录鼠标轨迹路径上面的每一个元素。但实际上,我们并不会对网页上所有的内容都感兴趣,我们只会对特定的内容感兴趣。因此,获取当前鼠标所在位置的元素,其实是一个伪需求,它根本没有什么实际上用处,因为噪声太大了,无用的数据太多了!
实际上,我觉得真正的需求应该是这样的:如果鼠标在网页上面某个元素停留时间超过 5 秒,那么获取这个元素。

但这样做太费时间了。每次都要等 5 秒,岂不是带薪摸鱼? 那需求能不能改成获取当前鼠标点击的元素呢? 如果你实践一下,你会发现,当你点击一个链接的时候,网页自动就跳转到另一个页面去了,并不能获取到你需要的数据。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-25发表,共计2498字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中