《前端实战总结》之使用解释器模式实现获取元素Xpath路径的算法

简介: 前端领域里基于javascript的设计模式和算法有很多,在很多复杂应用中也扮演着很重要的角色,接下来就介绍一下javascript设计模式中的解释器模式,并用它来实现一个获取元素Xpath路径的算法。


前端领域里基于javascript的设计模式和算法有很多,在很多复杂应用中也扮演着很重要的角色,接下来就介绍一下javascript设计模式中的解释器模式,并用它来实现一个获取元素Xpath路径的算法。


上期回顾




正文



1.解释器模式


对于一种语言,我们给出其文法表示形式(一种语言中的语法描述工具,用来定义语言的规则),并定义一种解释器,通过这种解释器来解释语言中定义的句子。


定义听起来可能比较抽象,举个例子比如我们常见的网站多语言,要实现多语言我们首先要预定语言的类型,提前设计不同语言的语料库,然后我们会根据配置和统一的变量规则来映射到不同语言。


2.元素的Xpath路径


XPath 用于在 XML 文档中通过元素和属性进行导航。虽然XPath 是用来查找XML节点,但同样可以用来查找HTML文档中的节点,因为HTML和XML结构类似。这里我们只考虑html,即元素在html页面中所处的路径。


那么如何快速获取元素的Xpath路径呢?其实也很简单,我们打开谷歌调试工具:



选中某个元素,如下,单机鼠标右键:



选中Copy XPath即可复制元素的Xpath路径。格式可能长这样:


//*[@id="juejin"]/div[2]/main/div/div[1]/article/div[1]

获取元素Xpath路径的应用场景很多,比如我们经常使用的python爬虫,利用爬虫框架可以通过Xpath路径很方便额控制页面中的某个dom节点,进而获取想要的数据和元素;又比如我们通过发送元素的Xpath路径给后端,后端可以统计某一功能的使用情况和交互数据;又比如分析用户在网站中浏览的热力分布图,路径画像等等。


3.js实现获取元素的Xpath路径


在实现之前,首先我们分析一下Xpath路径的结构,比如我们有一个页面,元素span的结构如下:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div>
       <span>我是徐小夕</span>
    </div>
</body>
</html>

那么我们的Xpath路径可能长这样:

HTML/BODY|HEAD/DIV/SPAN

从上面可以看出,我们的最右边一个元素都是目标元素,而最左边第一个元素都是最外层容器。要完成这个过程首先我们要通过元素的parentNode来获取当前元素的父元素,直到找到最顶层位置。但我们还需要注意的一点是,每找到上一层我们还要遍历该元素前面的兄弟元素previousSibling,如果这个兄弟元素名字和它后面的元素名字相同,则在元素名上+1.


第一步我们先实现一个遍历同级兄弟元素的方法getSameLevelName:


// 获取兄弟元素名称
function getSameLevelName(node){
    // 如果存在兄弟元素
    if(node.previousSibling) {
        let name = '',   // 返回的兄弟元素名称字符串
           count = 1,    // 紧邻兄弟元素中相同名称元素个数
           nodeName = node.nodeName,
           sibling = node.previousSibling;
        while(sibling){
            if(sibling.nodeType == 1 && sibling.nodeType === node.nodeType && sibling.nodeName){
                if(nodeName == sibling.nodeName){
                    name += ++count;
                }else {
                    // 重制相同紧邻节点名称节点个数
                    count = 1;
                    // 追加新的节点名称
                    name += '|' + sibling.nodeName.toUpperCase()
                }
            }
            sibling = sibling.previousSibling;
        }
        return name
    }else {
        // 不存在兄弟元素返回''
        return ''
    }
}

第二步,遍历文档树。

// XPath解释器
let Interpreter = (function(){
    return function(node, rwrap){
        // 路径数组
        let path = [],
        // 如果不存在容器节点,默认为document
        wrap = rwrap || document;
        // 如果当前节点等于容器节点
        if(node === wrap) {
            if(wrap.nodeType == 1) {
                path.push(wrap.nodeName.toUpperCase())
            }
            return path
        }
        // 如果当前节点的父节点不等于容器节点
        if(node.parentNode !== wrap){
            // 对当前节点的父节点执行遍历操作
            path = arguments.callee(node.parentNode, wrap)
        }
        // 如果当前节点的父元素节点与容器节点相同
        else {
            wrap.nodeType == 1 && path.push(wrap.nodeName.toUpperCase())
        }
        // 获取元素的兄弟元素的名称统计
        let siblingsNames = getSameLevelName(node)
        if(node.nodeType == 1){
            path.push(node.nodeName.toUpperCase() + siblingsNames)
        }
        // 返回最终的路径数组结果
        return path
    }
})()

有了这两个方法,我们就可以轻松获取元素的XPath路径啦,比如:

let path = Interpreter(document.querySelector('span'))
console.log(path.join('/'))

这样会返回开篇的一样的数据结构了.如:HTML/BODY|HEAD/DIV/SPAN

目录
相关文章
|
12天前
|
人工智能 编解码 算法
DeepSeek加持的通义灵码2.0 AI程序员实战案例:助力嵌入式开发中的算法生成革新
本文介绍了通义灵码2.0 AI程序员在嵌入式开发中的实战应用。通过安装VS Code插件并登录阿里云账号,用户可切换至DeepSeek V3模型,利用其强大的代码生成能力。实战案例中,AI程序员根据自然语言描述快速生成了C语言的base64编解码算法,包括源代码、头文件、测试代码和CMake编译脚本。即使在编译错误和需求迭代的情况下,AI程序员也能迅速分析问题并修复代码,最终成功实现功能。作者认为,通义灵码2.0显著提升了开发效率,打破了编程语言限制,是AI编程从辅助工具向工程级协同开发转变的重要标志,值得开发者广泛使用。
7862 67
DeepSeek加持的通义灵码2.0 AI程序员实战案例:助力嵌入式开发中的算法生成革新
|
4月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
15天前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
51 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
3月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
216 3
|
3月前
|
存储 前端开发 JavaScript
前端状态管理:Vuex 核心概念与实战
Vuex 是 Vue.js 应用程序的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。本教程将深入讲解 Vuex 的核心概念,如 State、Getter、Mutation 和 Action,并通过实战案例帮助开发者掌握在项目中有效使用 Vuex 的技巧。
|
4月前
|
Web App开发 缓存 监控
前端性能优化实战:从代码到部署的全面策略
前端性能优化实战:从代码到部署的全面策略
60 1
|
4月前
|
Web App开发 前端开发 JavaScript
前端性能优化实战:从代码到部署的全面指南
前端性能优化实战:从代码到部署的全面指南
71 1
|
4月前
|
缓存 前端开发 搜索推荐
前端性能优化实战:提升网页加载速度
前端性能优化实战:提升网页加载速度
101 1
|
4月前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
151 2
|
4月前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
93 2

热门文章

最新文章