I tried to achieve the function of clicking to obtain HTML elements and corresponding xpaths by executing JavaScript scripts and event filters, but none of them were the answers I wanted, I was too difficult.
The function I want is to open a webpage, and then click the button to enable the function of obtaining HTML elements and their xpaths, and then click on the page elements to output the results, but I have not been able to achieve it
My test code:
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()