如何在Python利用runJavaScript模拟鼠标移动页面的某个元素

问题:
之前看到一个回答是因为selenium框架被前段检测了,然后用PyQt5制作浏览器去实现爬虫,我现在也遇到了同样的问题,但是问题是在我不知道如何用Js的语句去模拟鼠标移动某个元素。

代码:

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_()

就是需要移动一个class名为smallImg的元素, 上面的输入和点击登录都完成了,现在卡在移动那块。

具体的移动需要:
鼠标移动到smallImg这个元素的坐标,点击并水平拖动一定的距离,然后释放。具体的移动距离可以先不考虑识别图片,我可以获取到需要移动的距离。

阅读 4.7k
2 个回答

不知道你所说的 "selenium 被检测到" 是什么情况,不过 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...


据我所知,目前(2018年8月10日)还没有 javascript 能实现真正可用的拖放效果。

不过你可以参考下面的文档,生成拖放事件,然后在指定元素上触发试试
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);

题外话:这类问题的难点通常不在拖放的起点或终点,你可能需要更精确的手段去控制整个拖放过程,比如在浏览器外生成鼠标事件。

我现在也遇到了一个问题,同求解答,利用pyqt5驱动浏览器的时候,注入js,我想全程使用js模拟点击,跳转页面等。但是当我使用相同的代码,runjavascript的时候,发现这几段代码一直在加载,导致我的步骤无法正常完成。

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_()
推荐问题
宣传栏