自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一日一技:Selenium 如何獲取鼠標(biāo)指向的元素?

開發(fā) 前端
每次都要等5秒,豈不是帶薪摸魚?那需求能不能改成獲取當(dāng)前鼠標(biāo)點(diǎn)擊的元素呢?如果你實(shí)踐一下,你會(huì)發(fā)現(xiàn),當(dāng)你點(diǎn)擊一個(gè)鏈接的時(shí)候,網(wǎng)頁自動(dòng)就跳轉(zhuǎn)到另一個(gè)頁面去了,并不能獲取到你需要的數(shù)據(jù)。

有一個(gè)同學(xué)在Gne的群里面咨詢?nèi)绾瓮ㄟ^Selenium獲取當(dāng)前鼠標(biāo)指向的元素,在我講了方法以后,他過了兩天又來問:

那么,我今天就來寫一篇文章,具體說說應(yīng)該怎么操作。

這個(gè)方法的核心,是借助JavaScript的事件(event)來獲取鼠標(biāo)所在的元素。然后再把這個(gè)元素傳遞給Selenium。我們先來第一步,不考慮Selenium,只使用JavaScript,如何獲取當(dāng)前鼠標(biāo)指向的元素呢?

我們首先需要知道在JavaScript中的一個(gè)事件句柄,叫做window.onmousemove。默認(rèn)情況下,它的值是null:

我們可以把它的值修改成一個(gè)函數(shù),這個(gè)函數(shù)接收一個(gè)event參數(shù),這樣當(dāng)鼠標(biāo)在網(wǎng)頁上移動(dòng)的時(shí)候,這個(gè)函數(shù)就會(huì)被調(diào)用。而event參數(shù)是一個(gè)對(duì)象,這個(gè)對(duì)象有兩個(gè)屬性.clientX和.clientY,分別表示鼠標(biāo)相當(dāng)于網(wǎng)頁的橫坐標(biāo)和縱坐標(biāo):

function track_mouse(event){
var x = event.clientX, y = event.clientY
console.log('當(dāng)前鼠標(biāo)所在位置的坐標(biāo):x=' + x + 'y=' + y)
}

運(yùn)行效果如下圖所示:

你執(zhí)行命令以后,只要在頁面上移動(dòng)鼠標(biāo),你就會(huì)在控制臺(tái)看到大量的坐標(biāo)被打印出來。

接下來,既然你有了當(dāng)前鼠標(biāo)所在位置的坐標(biāo),那么你只需要根據(jù)坐標(biāo)查詢到這個(gè)元素是什么就可以了。在JavaScript中,有一個(gè)函數(shù)叫做document.elementFromPoint,就能實(shí)現(xiàn)這個(gè)效果:

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

那么,如何把這個(gè)參數(shù)返回給Selenium呢?其實(shí)也非常簡單,我們?cè)O(shè)置一個(gè)全局變量window.hovered_element,然后把當(dāng)前鼠標(biāo)對(duì)應(yīng)的元素賦值給它。然后在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 // 當(dāng)前位置沒有元素
}
window.hovered_element = element
}
window.onmousemove = track_mouse

然后我們?cè)賮砜纯碨elenium中的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 // 當(dāng)前位置沒有元素
}
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'當(dāng)前鼠標(biāo)所在的標(biāo)簽為:{element.tag_name}, 其中的文本內(nèi)容為:{element.text}')
time.sleep(1)

運(yùn)行效果如下圖所示:

獲取到了當(dāng)前鼠標(biāo)所在的元素的標(biāo)簽和標(biāo)簽里面的文字。

到這里,這個(gè)同學(xué)需要的功能已經(jīng)完全實(shí)現(xiàn)了。

但可能有聰明的同學(xué)會(huì)發(fā)現(xiàn),他這個(gè)需求是有問題的。我們能看到至少有三個(gè)問題:

  • 因?yàn)閣indow.onmousemove太靈敏了,它的采樣時(shí)間是毫秒級(jí)別的,鼠標(biāo)稍稍移動(dòng)一點(diǎn)點(diǎn)就會(huì)生成一個(gè)事件。但是,一個(gè)元素的區(qū)域是很大的,在一個(gè)元素內(nèi)部移動(dòng)鼠標(biāo),其實(shí)根本沒有必要更新window.hovered_element。
  • 在Selenium里面,是通過while True每1秒查詢一次window.hovered_element,雖然我們已經(jīng)降低了頻率,但大家從上面的圖中可以看到,還是會(huì)獲取到很多重復(fù)的數(shù)據(jù)。這是由于有一些元素非常大,我們鼠標(biāo)如果在上面慢慢移動(dòng),時(shí)間會(huì)超過1秒,那么Selenium就會(huì)重復(fù)獲取到數(shù)據(jù)。
  • 由于window.onmousemove的采樣時(shí)間間隔很小,所以我們可以近似把鼠標(biāo)的移動(dòng)看做是連續(xù)的移動(dòng)。因此,這段代碼會(huì)記錄鼠標(biāo)軌跡路徑上面的每一個(gè)元素。但實(shí)際上,我們并不會(huì)對(duì)網(wǎng)頁上所有的內(nèi)容都感興趣,我們只會(huì)對(duì)特定的內(nèi)容感興趣。因此,獲取當(dāng)前鼠標(biāo)所在位置的元素,其實(shí)是一個(gè)偽需求,它根本沒有什么實(shí)際上用處,因?yàn)樵肼曁罅?,無用的數(shù)據(jù)太多了!

實(shí)際上,我覺得真正的需求應(yīng)該是這樣的:如果鼠標(biāo)在網(wǎng)頁上面某個(gè)元素停留時(shí)間超過5秒,那么獲取這個(gè)元素。

但這樣做太費(fèi)時(shí)間了。每次都要等5秒,豈不是帶薪摸魚?那需求能不能改成獲取當(dāng)前鼠標(biāo)點(diǎn)擊的元素呢?如果你實(shí)踐一下,你會(huì)發(fā)現(xiàn),當(dāng)你點(diǎn)擊一個(gè)鏈接的時(shí)候,網(wǎng)頁自動(dòng)就跳轉(zhuǎn)到另一個(gè)頁面去了,并不能獲取到你需要的數(shù)據(jù)。

責(zé)任編輯:武曉燕 來源: 未聞Code
相關(guān)推薦

2021-04-27 22:15:02

Selenium瀏覽器爬蟲

2021-10-15 21:08:31

PandasExcel對(duì)象

2022-03-12 20:38:14

網(wǎng)頁Python測(cè)試

2022-06-28 09:31:44

LinuxmacOS系統(tǒng)

2021-12-16 19:04:26

瀏覽器SeleniumChrome

2023-10-28 12:14:35

爬蟲JavaScriptObject

2024-07-30 08:11:16

2024-07-30 08:16:18

Python代碼工具

2020-12-04 06:39:25

爬蟲網(wǎng)頁

2024-11-11 00:38:13

Mypy靜態(tài)類型

2021-05-08 19:33:51

移除字符零寬

2021-04-05 14:47:55

Python多線程事件監(jiān)控

2024-11-13 09:18:09

2021-02-14 22:22:18

格式圖片 HTTP

2020-12-11 06:30:00

工具分組DataFrame

2023-10-29 09:16:49

代碼安全命令

2021-05-13 09:01:51

Cloud Flare瀏覽器網(wǎng)站

2021-04-12 21:19:01

PythonMakefile項(xiàng)目

2020-05-19 13:55:38

Python加密密碼

2024-02-20 22:13:48

Python項(xiàng)目Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)