jquery逆向css selector path生成
场景:
一般情况我们都是已知css选择器的情况下,去操作dom元素,而在做爬虫时,为了方便的使用可视化的方式,让用户能够快速选区要采集的元素节点,需要在页面上点击某个元素后自动获取其selector。
思路:
从点击元素开始向上(父节点)遍历,若遍历过程中的某个选择器能够唯一确定这个元素,则返回。当遇到有id属性的元素时直接返回。
实现:
/**
* 获取css path
* @param callback
* callback接收两个参数:元素的css路径,选择元素的jq对象
*/
function getCssPath(callback) {
let all = $('*');
all.click(function () {
let path = cssPath($(this));
if ($(path).hasClass('_selected')) {
$(path).removeClass('_selected');
} else {
$(path).addClass('_selected');
}
callback(path, $(this));
return false;
})
}
function cssPath(el) {
let path = [];
while (el && el[0].tagName !== 'HTML') {
let selector = el[0].tagName.toLowerCase();
if (el.attr('id')) {
selector += '#' + el.attr('id');
path.unshift(selector);
break;
} else {
if (el.attr('class') && el.attr('class') !== '' && el.attr('class').trim() !== '_selected' && selector !== 'input') {
let classStr = el.attr('class');
let cl = '.' + classStr.trim().split(/\s+/).join('.');
if ($(selector + cl + '>' + (path.length > 0 ? path.join(" > ") : '')).length === 1) {
path.unshift(selector + cl);
break;
}
let suffixLen = el.nextAll();
let nth = el.prevAll().length + 1;
if (nth !== 1 || suffixLen !== 0)
selector += ":nth-child(" + nth + ")";
} else if (selector === 'input' && el.attr('name')) {
if ($(selector + '[name=' + el.attr('name') + ']').length === 1) {
path.unshift(selector + '[name=' + el.attr('name') + ']');
break;
}
} else {
let nth = el.prevAll().length + 1;
if (nth !== 1)
selector += ":nth-child(" + nth + ")";
}
}
path.unshift(selector);
el = el.parent();
}
return path.join(" > ");
}
其中_selected类如下:
._selected{
background-color:green !important;
}
使用方式:
$(document).ready(function () {
setTimeout(function () {
getCssPath(function (path, el) {
alert($(path).text() + ':' + el.text())
});
}, 2000)
});
结果对比:
浏览器copy selector生成的path:
#app > div > div.app-frame.h-layout.h-layout-has-sider.h-layout-sider-fixed > div.h-layout.h-layout-header-fixed > div.h-layout-content > div.app-frame-content > div > div > div:nth-child(2) > div > div.h-panel-bar > div.h-panel-title._selected
本代码生成的path:
div.h-row > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1)
相对于浏览器生成的来说,更简洁
网络上志同道合,我们一起学习网络安全,一起进步,QQ群:694839022