Можно ли щелкнуть внутри собственного веб-приложения? - PullRequest
1 голос
/ 01 мая 2019

Я создал веб-приложение PyQt5, которое переходит на https://www.google.com/ со следующим кодом:

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *

import sys

class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("My Window")

        self.browser = QWebEngineView()
        self.browser.setUrl( QUrl("www.google.com") )
        self.setCentralWidget(self.browse) 

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Идея состоит в том, что я хочу манипулировать кликами внутри приложения, поэтому на сайте GoogleНапример, перемещение мыши в определенные места (x, y), не влияя на сам компьютер, как это делает pyautogui, что означает, что я могу запускать код, который случайным образом щелкает внутри веб-приложения, в то время как я могу делать обычные действия наПК, без влияет на мышь.

Я буду рад узнать, возможно ли это или нет.И если да, то как?

Примечание: у меня нет опыта работы с Python

Ответы [ 2 ]

1 голос
/ 01 мая 2019

Если это не встроенное приложение, вы всегда можете проанализировать html, найти кнопку и «нажать» кнопку, либо запросив путь, по которому она будет идти, либо с помощью анализатора javascript.

После кода API будет выглядеть примерно так:

parsed_response.find(my_button).click()

Если вы не настаиваете на написании своего, уже есть один сделанный, selenium.

Чтобы показать маленький пример

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get("www.website.com")
login_input = driver.find_element_by_id(id)
login_input.send_keys(my_login)
login_input.send_keys(Keys.ENTER)
# Or you can do something like
# submit_button = driver.find_element_by_id(submitbutton)
# submit_button.click()

Сила селена огромна, но я всегда добавляю это как примечание, когда отвечаю на вопросы о веб-очистке. Пожалуйста, проверьте /robots.txt, прежде чем использовать этот сайт с вашим ботом.

0 голосов
/ 01 мая 2019

Вы можете эмулировать щелчок, отправив QMouseEvent, в случае QWebEngineView щелчок должен быть выполнен для внутреннего виджета, являющегося частью частного API Qt, но с небольшой логикой, к которой можно получить доступ: используя findChildren и QMetaObject.

В следующем примере нажмите на позицию 400, 200, которая в моем случае является баннером Google, который откроет соответствующую информацию.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle("My Window")

        self.browser = QtWebEngineWidgets.QWebEngineView()
        self.browser.setUrl(QtCore.QUrl("https://www.google.com/"))
        self.setCentralWidget(self.browser)
        self.browser.loadFinished.connect(self.on_loadFinished)

    @QtCore.pyqtSlot(bool)
    def on_loadFinished(self, ok):
        if not ok:
            return
        w = None
        for child in self.browser.findChildren(QtWidgets.QWidget):
            if (
                child.metaObject().className()
                == "QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget"
            ):
                w = child
                break
        if w is not None:
            self.emulate_click(w, QtCore.QPoint(400, 200))

    def emulate_click(self, widget, pos):
        event_press = QtGui.QMouseEvent(
            QtCore.QEvent.MouseButtonPress,
            pos,
            QtCore.Qt.LeftButton,
            QtCore.Qt.LeftButton,
            QtCore.Qt.NoModifier,
        )
        QtCore.QCoreApplication.postEvent(widget, event_press)
        event_release = QtGui.QMouseEvent(
            QtCore.QEvent.MouseButtonRelease,
            pos,
            QtCore.Qt.LeftButton,
            QtCore.Qt.LeftButton,
            QtCore.Qt.NoModifier,
        )
        QtCore.QCoreApplication.postEvent(widget, event_release)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

Если у вас есть дополнительная информация, такая как id или xpath, выможно нажать, используя JavaScript:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle("My Window")

        self.browser = QtWebEngineWidgets.QWebEngineView()
        self.browser.setUrl(QtCore.QUrl("https://www.google.com/"))
        self.setCentralWidget(self.browser)
        self.browser.loadFinished.connect(self.on_loadFinished)

    @QtCore.pyqtSlot(bool)
    def on_loadFinished(self, ok):
        if not ok:
            return
        xpath = r"//body[@id='gsr']/div[@id='viewport']/div[@id='main']/span[@id='body']/center/div[@id='lga']/div[@id='hplogo']/a/img[1]"
        s = (
            """
            (function() {
                var banner = document.evaluate("%s", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                banner.click()
            })()"""
            % xpath
        )
        self.browser.page().runJavaScript(s)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
...