鍍金池/ 問(wèn)答/Python  HTML/ 如何在Python利用runJavaScript模擬鼠標(biāo)移動(dòng)頁(yè)面的某個(gè)元素

如何在Python利用runJavaScript模擬鼠標(biāo)移動(dòng)頁(yè)面的某個(gè)元素

問(wèn)題:
之前看到一個(gè)回答是因?yàn)閟elenium框架被前段檢測(cè)了,然后用PyQt5制作瀏覽器去實(shí)現(xiàn)爬蟲,我現(xiàn)在也遇到了同樣的問(wèn)題,但是問(wèn)題是在我不知道如何用Js的語(yǔ)句去模擬鼠標(biāo)移動(dòng)某個(gè)元素。

代碼:

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl
import pyautogui
import time
import sys
app = QApplication([])
view = QWebEngineView()
view.load(QUrl("url"))
view.show()
page = view.page()
#a = 0
#global a

def test():
    
    page.runJavaScript("$('#account').val(123)")
    page.runJavaScript("$('#password').val(123)")
    page.runJavaScript("$('#btn-login').trigger('click')")                   
    time.sleep(1)
#    page.runJavaScript("alert($('#distance').html())")
    page.runJavaScript("$('.smallImg').trigger('click')")
    
#view.loadFinished.connect(test)
app.exec_()

就是需要移動(dòng)一個(gè)class名為smallImg的元素, 上面的輸入和點(diǎn)擊登錄都完成了,現(xiàn)在卡在移動(dòng)那塊。

具體的移動(dòng)需要:
鼠標(biāo)移動(dòng)到smallImg這個(gè)元素的坐標(biāo),點(diǎn)擊并水平拖動(dòng)一定的距離,然后釋放。具體的移動(dòng)距離可以先不考慮識(shí)別圖片,我可以獲取到需要移動(dòng)的距離。

回答
編輯回答
厭惡我

不知道你所說(shuō)的 "selenium 被檢測(cè)到" 是什么情況,不過(guò) selenium 提供了拖放功能

element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")

from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element, target).perform()

參考 https://selenium-python.readt...


據(jù)我所知,目前(2018年8月10日)還沒(méi)有 javascript 能實(shí)現(xiàn)真正可用的拖放效果。

不過(guò)你可以參考下面的文檔,生成拖放事件,然后在指定元素上觸發(fā)試試
https://developer.mozilla.org...

var event = new DragEvent(type, DragEventInit);

// Listen for the event.
elem.addEventListener('build', function (e) { /* ... */ }, false);

// Dispatch the event.
elem.dispatchEvent(event);

題外話:這類問(wèn)題的難點(diǎn)通常不在拖放的起點(diǎn)或終點(diǎn),你可能需要更精確的手段去控制整個(gè)拖放過(guò)程,比如在瀏覽器外生成鼠標(biāo)事件。

2017年2月17日 01:32
編輯回答
九年囚

我現(xiàn)在也遇到了一個(gè)問(wèn)題,同求解答,利用pyqt5驅(qū)動(dòng)瀏覽器的時(shí)候,注入js,我想全程使用js模擬點(diǎn)擊,跳轉(zhuǎn)頁(yè)面等。但是當(dāng)我使用相同的代碼,runjavascript的時(shí)候,發(fā)現(xiàn)這幾段代碼一直在加載,導(dǎo)致我的步驟無(wú)法正常完成。

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl
import time

app = QApplication([])
view = QWebEngineView()
view.load(QUrl("http://www.flyscoot.com/"))
view.show()
page = view.page()

def test1():
    # page.runJavaScript("alert('hello world')")# go
    page.runJavaScript("document.getElementsByClassName('radio-inline')[1].click()")
    page.runJavaScript("document.getElementById('oneway_from').value='廣州 (CAN)'")
    page.runJavaScript("document.getElementById('oneway_to').value='新加坡 (SIN)'")
    page.runJavaScript("document.getElementById('oneway_departuredate').value='2018年8月31日'")
    page.runJavaScript("document.getElementsByClassName('btn--booking')[1].click()")
    ############################ 分割線 ##################################
    page.runJavaScript("document.getElementsByClassName('price--sale')[0].click()")
    page.runJavaScript("document.getElementsByClassName('heading-4')[0].click()")
    page.runJavaScript("document.getElementsByClassName('btn-submit')[0].click()")
    ############################ 分割線 ##################################
    page.runJavaScript("document.getElementById('selecttitle1').value='MR'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__First').value='tom'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__Last').value='wang'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__DayOfBirth').value='12'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__MonthOfBirth').value='12'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__YearOfBirth').value='1995'")
    page.runJavaScript("document.getElementById('revPassengersInput_PassengerInfantModels_PassengersInfo_0__Nationality').value='CN'")
    page.runJavaScript("document.getElementsByClassName('radio-inline').click()")
    page.runJavaScript("document.getElementsByClassName('btn-submit').click()")
    ############################ 分割線 ##################################
    page.runJavaScript("document.getElementsByClassName('btn-submit').click()")
    page.runJavaScript("document.getElementById('nextFlightButton').click()")
    ############################ 分割線 ##################################
    page.runJavaScript("document.getElementsByClassName('btn-submit').click()")
    ############################ 分割線 ##################################
    page.runJavaScript("document.getElementById('revContactInput_WorkPhone_Number').value='xxx'")
    page.runJavaScript("document.getElementById('emailContact').value='xxx'")
    page.runJavaScript("document.getElementsByClassName('form-control').value='xxx'")
    page.runJavaScript("document.getElementsByClassName('radio-inline').click()")
    page.runJavaScript("document.getElementById('revContactInput_ContactViewModel_AddressLine1').value='guojiaqiao'")
    page.runJavaScript("document.getElementById('revContactInput_ContactViewModel_City').value='chengdu'")
    page.runJavaScript("document.getElementById('revContactInput_ContactViewModel_CountryCode').value='CN'")
    page.runJavaScript("document.getElementById('revContactInput_ContactViewModel_ProvinceState').value='FJ'")
    page.runJavaScript("document.getElementById('revContactInput_ContactViewModel_PostalCode').value='401122'")
    page.runJavaScript("document.getElementsByClassName('tab')[2].click()") # Alipay
    page.runJavaScript("document.getElementsByClassName('push-checkbox')[1].click()") # 接受條約
    page.runJavaScript("document.getElementsByClassName('btn-submit').click()") # go

view.loadFinished.connect(test1)

app.exec_()
2018年2月23日 17:19