pyppeteer 有提供鼠標(biāo)滑動(dòng)的方法,但是單獨(dú)調(diào)用 pyppeteer 滑動(dòng)方法是無(wú)法通過驗(yàn)證的,必須使滑動(dòng)軌跡更加接近人工的方式才行。
這里我們先了解一下pyppeteer是如何實(shí)現(xiàn)滑動(dòng)的
一、pyppeteer 提供的滑動(dòng)方法API
iframe.hover(slide_id) # 移動(dòng)鼠標(biāo)到滑塊上方(聚焦)
page.mouse.down() # 按下鼠標(biāo)
page.mouse.move() # 移動(dòng)鼠標(biāo)
page.mouse.up() # 松開鼠標(biāo)
根據(jù)以上的4個(gè)方法組合就可以實(shí)現(xiàn)滑動(dòng)。
二、滑動(dòng)方法API詳解
- 1.1 iframe.hover(slide_id) , slide_id是滑塊的css選擇器,例如'span#nc_1_n1z', 這個(gè)根據(jù)實(shí)際情況來(lái)指定。
這里需要注意的是iframe,什么意思呢?很多人給的參考都是直接調(diào)用page.hover(slide_id) ,但是很多情況在page里直接找調(diào)用hover(slide_id)是無(wú)法聚焦到滑塊上的,這是因?yàn)榛瑝K往往會(huì)加載在一個(gè)子頁(yè)面 iframe 上,我們需要在找到 iframe ,然后在 iframe 上調(diào)用 hover 來(lái)聚焦滑塊。
如果滑塊已經(jīng)頁(yè)面page中,則直接調(diào)用 page.hover(slide_id), 無(wú)需這么復(fù)雜
-
1.2 如何找到 iframe
屏幕快照 2019-08-01 15.01.33.png
首先F12調(diào)出元素檢查,查看滑塊所在的窗口是否有 iframe,(或者直接 ctrl + f 搜索 iframe),
1.找出 iframe 的css選擇器 :iframe#sufei-dialog-content (你應(yīng)該根據(jù)實(shí)際情況填寫)
2.在page中找到此 WebElement元素節(jié)點(diǎn): iframe_element = await page.J('iframe#sufei-dialog-content')
此時(shí)還 無(wú)法在 iframe_element 上調(diào)用hover() 函數(shù),因?yàn)閕frame_element此時(shí)是 ElementHandle Class,而我們需要的是Frame Class
3.將ElementHandle Class強(qiáng)轉(zhuǎn)成Frame Class :iframe =await iframe_element.contentFrame()
完整的方法應(yīng)該是:
async def iframe_id2frame(iframe_id, page)
iframe_element = await page.J(iframe_id)
if iframe_element:
iframe =await iframe_element.contentFrame()
return iframe
else:
return None
slide_id = '#span……'
iframe_id = 'iframe.sd……'
iframe = await iframe_id2frame(iframe_id)
if iframe:
iframe.hover(slide_id)
2 page.mouse.down() 按下鼠標(biāo)
這個(gè)沒什么好說(shuō)的,直接執(zhí)行就好3 page.mouse.move()
源碼:async def move(self, x: float, y: float, options: dict = None,
**kwargs: Any) -> None:源碼鏈接
其中x,y 是指移動(dòng)到絕對(duì)橫向,縱向坐標(biāo),options是一個(gè)字典,只有一個(gè)鍵steps,用來(lái)控制速度。
例如你想要鼠標(biāo)向右移動(dòng)500像素,則 x為當(dāng)前橫坐標(biāo) + 500,y為當(dāng)前縱坐標(biāo)不變。
當(dāng)前的橫坐標(biāo)、縱坐標(biāo)獲取有些麻煩,網(wǎng)上也有人這樣來(lái)滑動(dòng):
await page.mouse(10000,0) ,這樣是指把鼠標(biāo)橫行移動(dòng)到10000,縱向移動(dòng)到零,滑動(dòng)無(wú)法縱向移動(dòng),所以只能看到橫行的移動(dòng)效果。沒有添加第三個(gè)參數(shù),則默認(rèn)一步完成 {'steps':1}
注意:這里的坐標(biāo)和像素值是一致的,左上角為起點(diǎn)(0,0)
steps 是指分成幾步來(lái)完成,steps越大,滑動(dòng)速度越慢。(在源碼中,steps是指移動(dòng)到指定x,y 分段滑動(dòng)的次數(shù),但是每次啟動(dòng)滑動(dòng)都會(huì)花費(fèi)一定時(shí)間,可以認(rèn)為steps是滑動(dòng)的速度)
- 4 page.mouse.up() 松開鼠標(biāo)
到現(xiàn)在,我們已經(jīng)完成了滑動(dòng)驗(yàn)證的功能,當(dāng)然它還不夠完善,但基本的功能已經(jīng)齊全了,在下一節(jié),介紹一下控制滑動(dòng)軌跡,模擬人工滑動(dòng)。
async def iframe_id2frame(iframe_id, page)
iframe_element = await page.J(iframe_id)
if iframe_element:
iframe =await iframe_element.contentFrame()
return iframe
else:
return None
# 1 聚焦
slide_id = '#span……'
iframe_id = 'iframe.sd……'
iframe = await iframe_id2frame(iframe_id)
if iframe:
# 如果滑塊在頁(yè)面page中,則直接調(diào)用 page.hover(slide_id),無(wú)需這么復(fù)雜
await iframe.hover(slide_id)
# 2 按下鼠標(biāo)
await page.mouse.down()
# 3 滑動(dòng)
await page.mouse.move(10000,0)
# 4 松開鼠標(biāo)
await page.mouse.up()
注意1:這里pyppeteer涉及到 page 與 iframe,peppeteer的功能是以frame為基礎(chǔ)單位來(lái)實(shí)現(xiàn)的,page 的功能 iframe 都有,page 在執(zhí)行函數(shù)時(shí),會(huì)先調(diào)用 frame = self.mainFrame,然后在frame上執(zhí)行功能。mainFrame就是最外面的那個(gè)Frame
注意2: mouse對(duì)象是page/mainFrame對(duì)象所獨(dú)有的,在子frame中,也就是iframe 中不能調(diào)用mouse對(duì)象。
