栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

有没有办法在浏览器的Pyqt5中获取页面的XPATH?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

有没有办法在浏览器的Pyqt5中获取页面的XPATH?

为了回答这个问题,我使用了以下答案:

  • 获取被单击的项目:https : //stackoverflow.com/a/9012576

  • 根据项目获取XPATH:https://stackoverflow.com/a/58677712

  • 运行js脚本并将信息发送到python:https : //stackoverflow.com/a/55294356

将所有这些部分结合在一起,您将获得以下解决方案:

├── main.py└── xpath_from_element.js

main.py

import osfrom PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets, QtWebChannelfrom jinja2 import TemplateCURRENT_DIR = os.path.dirname(os.path.realpath(__file__))class Element(QtCore.QObject):    def __init__(self, name, parent=None):        super(Element, self).__init__(parent)        self._name = name    @property    def name(self):        return self._name    def script(self):        return ""class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):    def __init__(self, parent=None):        super(WebEnginePage, self).__init__(parent)        self.loadFinished.connect(self.onLoadFinished)        self._objects = []        self._scripts = []    def add_object(self, obj):        self._objects.append(obj)    @QtCore.pyqtSlot(bool)    def onLoadFinished(self, ok):        print("Finished loading: ", ok)        if ok: self.load_qwebchannel() self.add_objects()    def load_qwebchannel(self):        file = QtCore.QFile(":/qtwebchannel/qwebchannel.js")        if file.open(QtCore.QIODevice.ReadOnly): content = file.readAll() file.close() self.runJavascript(content.data().depre())        if self.webChannel() is None: channel = QtWebChannel.QWebChannel(self) self.setWebChannel(channel)    def add_objects(self):        if self.webChannel() is not None: objects = {obj.name: obj for obj in self._objects} self.webChannel().registerObjects(objects) _script = """ {% for obj in objects %} var {{obj}}; {% endfor %} new QWebChannel(qt.webChannelTransport, function (channel) { {% for obj in objects %}     {{obj}} = channel.objects.{{obj}}; {% endfor %} });  """ self.runJavascript(Template(_script).render(objects=objects.keys())) for obj in self._objects:     if isinstance(obj, Element):         self.runJavascript(obj.script())class Helper(Element):    xpathClicked = QtCore.pyqtSignal(str)    def script(self):        js = ""        file = QtCore.QFile(os.path.join(CURRENT_DIR, "xpath_from_element.js"))        if file.open(QtCore.QIODevice.ReadOnly): content = file.readAll() file.close() js = content.data().depre()        js += """        document.addEventListener('click', function(e) { e = e || window.event; var target = e.target || e.srcElement; var xpath = Elements.DOMPath.xPath(target, false);  {{name}}.receive_xpath(xpath);        }, false);"""        return Template(js).render(name=self.name)    @QtCore.pyqtSlot(str)    def receive_xpath(self, xpath):        self.xpathClicked.emit(xpath)if __name__ == "__main__":    import sys    app = QtWidgets.QApplication(sys.argv)    xpath_helper = Helper("xpath_helper")    xpath_helper.xpathClicked.connect(lambda xpath: print("clicked", xpath))    view = QtWebEngineWidgets.QWebEngineView()    page = WebEnginePage()    page.add_object(xpath_helper)    view.setPage(page)    view.load(QtCore.QUrl("https://www.qt.io"))    view.show()    sys.exit(app.exec_())

xpath_from_element.js

// Copyright 2018 The Chromium Authors. All rights reserved.// Use of this source pre is governed by a BSD-style license that can be// found in the LICENSE file.Elements = {};Elements.DOMPath = {};Elements.DOMPath.xPath = function (node, optimized) {    if (node.nodeType === Node.document_NODE) {        return '/';    }    const steps = [];    let contextNode = node;    while (contextNode) {        const step = Elements.DOMPath._xPathValue(contextNode, optimized);        if (!step) { break;        }  // Error - bail out early.        steps.push(step);        if (step.optimized) { break;        }        contextNode = contextNode.parentNode;    }    steps.reverse();    return (steps.length && steps[0].optimized ? '' : '/') + steps.join('/');};Elements.DOMPath._xPathValue = function (node, optimized) {    let ownValue;    const ownIndex = Elements.DOMPath._xPathIndex(node);    if (ownIndex === -1) {        return null;    }  // Error.    switch (node.nodeType) {        case Node.ELEMENT_NODE: if (optimized && node.getAttribute('id')) {     return new Elements.DOMPath.Step('/Elements.DOMPath._xPathIndex = function (node) {    // Returns -1 in case of error, 0 if no siblings matching the same expression,    // <XPath index among the same expression-matching sibling nodes> otherwise.    function areNodesSimilar(left, right) {        if (left === right) { return true;        }        if (left.nodeType === Node.ELEMENT_NODE && right.nodeType === Node.ELEMENT_NODE) { return left.localName === right.localName;        }        if (left.nodeType === right.nodeType) { return true;        }        // XPath treats CDATA as text nodes.        const leftType = left.nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left.nodeType;        const rightType = right.nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right.nodeType;        return leftType === rightType;    }    const siblings = node.parentNode ? node.parentNode.children : null;    if (!siblings) {        return 0;    }  // Root node - no siblings.    let hasSameNamedElements;    for (let i = 0; i < siblings.length; ++i) {        if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) { hasSameNamedElements = true; break;        }    }    if (!hasSameNamedElements) {        return 0;    }    let ownIndex = 1;  // XPath indices start with 1.    for (let i = 0; i < siblings.length; ++i) {        if (areNodesSimilar(node, siblings[i])) { if (siblings[i] === node) {     return ownIndex; } ++ownIndex;        }    }    return -1;  // An error occurred: |node| not found in parent's children.};Elements.DOMPath.Step = class {        constructor(value, optimized) {        this.value = value;        this.optimized = optimized || false;    }        toString() {        return this.value;    }};


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/648229.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号