pyside6 中的 QWebEngineView 如何通过点击或 JS 交互实现 element 和 xpath 元素打开页面

How can QWebEngineView in pyside6 achieve element and xpath elements for opening pages by clicking or JS interaction

提问人:mmww 提问时间:10/27/2023 更新时间:10/27/2023 访问量:22

问:

我试图通过执行JavaScript脚本和事件过滤器来实现点击获取HTML元素和相应的xpath的功能,但是它们都不是我想要的答案,我太难了。

我想要的功能是打开一个网页,然后点击按钮开启获取HTML元素及其xpaths的功能,然后点击页面元素输出结果,但是一直无法实现

我的测试代码:

from PySide6.QtCore import QUrl, Qt, QEvent
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton
from PySide6.QtWebEngineWidgets import QWebEngineView


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.web_view = QWebEngineView()
        self.web_view.load(QUrl("https://www.example.com"))  

        self.button = QPushButton("Run JavaScript")


        self.button.clicked.connect(self.execute_js)


        layout = QVBoxLayout()
        layout.addWidget(self.web_view)
        layout.addWidget(self.button)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

    def execute_js(self):

        self.web_view.focusProxy().installEventFilter(self)
        

    def callback(self, result):

        print(result, len(str(result)), type(result))

        self.web_view.focusProxy().removeEventFilter(self)

    def eventFilter(self, obj, event):
        # print(obj , self.web_view, event, esvent.type())
        js_code = '''
            document.body.style.cursor = 'crosshair';   

            var element;
            var aa = 123;
            disableLinksAndButtons(); 


            document.addEventListener('mouseover', mouseoverEvent); 
            document.addEventListener('mouseout', mouseoutEvent);   
            document.addEventListener('click', clickEvent);         


            function mouseoverEvent(event) {
                element = event.target;
                element.style.outline = '2px solid red';    
            }
            
            function mouseoutEvent(event){
                element.style.outline = '';     
            }
            
            function clickEvent(event){
                element.style.outline = '';
                element = event.target;
                var html = element.outerHTML;   
                var xpath = getXPath(element);  
                removeEventListener();      
                enableLinksAndButtons();    
            }

            // Get XPath
            function getXPath(element) {
                if (element.id !== "") { 
                    return '//*[@id="' + element.id + '"]'; 
                }
                if (element === document.body) { 
                    return "/html/body"; 
                }
                
                var index = 1;
                const childNodes = element.parentNode ? element.parentNode.childNodes : []; 
                var siblings = childNodes;
                
                for (var i = 0; i < siblings.length; i++) {
                    var sibling = siblings[i];
                    if (sibling === element) { 
                    return (
                        getXPath(element.parentNode) +
                        "/" +
                        element.tagName.toLowerCase() +
                        "[" +
                        index +
                        "]"
                    );
                    }
                    if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { 
                    index++; 
                    }
                }
            }


            function removeEventListener(){
                document.removeEventListener('mouseover', mouseoverEvent);
                document.removeEventListener('mouseout', mouseoutEvent);
                document.removeEventListener('click', clickEvent);
            }

            function disableLinksAndButtons() {
                var links = document.getElementsByTagName('a');
                for (var i = 0; i < links.length; i++) {
                    links[i].onclick = function(event) {
                        event.preventDefault(); 
                    };
                }

                var buttons = document.getElementsByTagName('button');
                for (var j = 0; j < buttons.length; j++) {
                    buttons[j].onclick = function(event) {
                        event.preventDefault(); 
                    };
                }
            }


            function enableLinksAndButtons() {
                var links = document.getElementsByTagName('a');
                for (var i = 0; i < links.length; i++) {
                    links[i].onclick = null; 
                }

                var buttons = document.getElementsByTagName('button');
                for (var j = 0; j < buttons.length; j++) {
                    buttons[j].onclick = null; 
                }
            }
        '''
        # print(event.type())
        # self.web_view.page().runJavaScript(js_code)
        if event.type() == QEvent.MouseButtonPress or event.type() == QEvent.MouseMove:
            mouse_event = event
            if mouse_event.button() == Qt.LeftButton:
                print("Left mouse button clicked!")
                return True  
            script = """
                
            document.addEventListener('click', clickEvent); 

            # !!!It can't even deliver 123 back
            function clickEvent(event) {
                element = event.target;
                alert(element);
                return 123;
            }
            mouseoverEvent();
            """
            self.web_view.page().runJavaScript(script, 0, self.callback)

        return super().eventFilter(obj, event)

app = QApplication([])

window = MainWindow()
window.show()

app.exec()
python pyside6 qweb qwebengineview

评论


答: 暂无答案