詳解Python?Selenium如何獲取鼠標(biāo)指向的元素
有一個(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)頁(yè)上移動(dòng)的時(shí)候,這個(gè)函數(shù)就會(huì)被調(diào)用。而event
參數(shù)是一個(gè)對(duì)象,這個(gè)對(duì)象有兩個(gè)屬性.clientX
和.clientY
,分別表示鼠標(biāo)相當(dāng)于網(wǎng)頁(yè)的橫坐標(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í)行命令以后,只要在頁(yè)面上移動(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í)也非常簡(jiǎn)單,我們?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)?code>window.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)頁(yè)上所有的內(nèi)容都感興趣,我們只會(huì)對(duì)特定的內(nèi)容感興趣。因此,獲取當(dāng)前鼠標(biāo)所在位置的元素,其實(shí)是一個(gè)偽需求,它根本沒有什么實(shí)際上用處,因?yàn)樵肼曁罅?,無(wú)用的數(shù)據(jù)太多了!
實(shí)際上,我覺得真正的需求應(yīng)該是這樣的:如果鼠標(biāo)在網(wǎng)頁(yè)上面某個(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)頁(yè)自動(dòng)就跳轉(zhuǎn)到另一個(gè)頁(yè)面去了,并不能獲取到你需要的數(shù)據(jù)。
到此這篇關(guān)于詳解Python Selenium如何獲取鼠標(biāo)指向的元素的文章就介紹到這了,更多相關(guān)Selenium鼠標(biāo)指向元素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟
這篇文章主要介紹了Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10Python實(shí)現(xiàn)格式化輸出的實(shí)例詳解
這篇文章主要為大家介紹了Python語(yǔ)法中實(shí)現(xiàn)格式化輸出的方法,本文通過幾個(gè)實(shí)例為大家進(jìn)行了詳細(xì)的講解,感興趣的小伙伴可以了解一下2022-08-08淺談django model的get和filter方法的區(qū)別(必看篇)
下面小編就為大家?guī)硪黄獪\談django model的get和filter方法的區(qū)別(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05Windows環(huán)境打包python工程為可執(zhí)行程序的詳細(xì)過程
我的開發(fā)環(huán)境是windows7,然后系統(tǒng)是64位,安裝的python和wxpython都是32位的,本文記錄我怎樣用pyinstaller打包我用python開發(fā)的工程,在網(wǎng)上搜索了很多資源,基本上都是不全的,所以我在這兒記錄一下這個(gè)比較完整的過程,一起看看吧2024-01-01Python后臺(tái)開發(fā)Django會(huì)話控制的實(shí)現(xiàn)
這篇文章主要介紹了Python后臺(tái)開發(fā)Django會(huì)話控制的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Python高級(jí)文件操作之shutil庫(kù)詳解
這篇文章主要介紹了Python高級(jí)文件操作之shutil庫(kù)詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有很大的幫助,需要的朋友可以參考下2021-05-05python使用mysqldb連接數(shù)據(jù)庫(kù)操作方法示例詳解
這篇文章主要介紹了python mysqldb使用方法,大家參考使用2013-12-12