《前端5分鐘》之使用解釋器模式實現獲取元素Xpath路徑的算法

2020-12-25 酷扯兒

本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫

前端領域裡基於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, wrap){

// 路徑數組

let path = [],

// 如果不存在容器節點,默認為document

wrap = wrap || 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() + sublingsNames)

}

// 返回最終的路徑數組結果

return path

}

})()

有了這兩個方法,我們就可以輕鬆獲取元素的XPath路徑啦,比如:

let path = Interpreter(document.querySelector('span'))

console.log(path.join('/'))

這樣會返回開篇的一樣的數據結構了.如:HTML/BODY|HEAD/DIV/SPAN

相關焦點

  • 通過xpath快速獲取頁面元素的方法
    路徑表達式結果bookstore選取 bookstore 元素的所有子節點。/bookstore選取根元素 bookstore。注釋:假如路徑起始於正斜槓( / ),則此路徑始終代表到某元素的絕對路徑!bookstore/book選取屬於 bookstore 的子元素的所有 book 元素。//book選取所有 book 子元素,而不管它們在文檔中的位置。
  • XPATH元素定位詳解
    這時候我們不得不藉助Xpath和Css來實現元素定位了Xpath定位1.xpath簡介XPath是XML Path的簡稱,它是一種用來確定XML(可擴展標記語言)文檔中某部分位置的語言。由於HTML文檔本身就是一個標準的XML頁面,因此我們可以使用XPath的語法來定位頁面元素。
  • 解釋器模式
    解釋器模式是一種類行為型模式,其主要優點如下:解釋器模式的主要缺點如下:執行效率較低:解釋器模式中通常使用大量的循環和遞歸調用,當要解釋的句子較複雜時,其運行速度很慢,且代碼的調試過程也比較麻煩。下圖所示是「我是大學生」的語法樹:有了以上基礎知識,現在來介紹解釋器模式的結構就簡單了。解釋器模式的結構與組合模式相似,不過其包含的組成元素比組合模式多,而且組合模式是對象結構型模式,而解釋器模式是類行為型模式。
  • python 爬蟲 | 解析庫之 XPath(1)
    所以今天我們就詳細介紹下 XPath 解析庫的使用,此教程一共分為三篇,今天是第一篇。XPath學習過 web 相關知識的同學應該知道,前端界面是由很多個節點構建而成的,它可以定義 id、class 或其他屬性。而且節點之間還有層次關係,在網頁中我們就可以通過 XPath 或 CSS 選擇器來定位一個或多個節點。那什麼是 XPath?
  • 數據提取工具lxml及xpath
    在lxml中使用xpath也非常的簡單,如下:from lxml import etree   text = '''   <div>      <ul>           <li><a href="link1.html">first item</a></li>
  • 設計模式之——解釋器模式
    解釋器模式的核心思想是:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,使用該解釋器來解釋語言中的句子。聽完這句話話是不是頓時感覺一臉懵?什麼語言、文法、句子,都是些什麼鬼?別慌讓「菜鳥」來給你分析一波。
  • Python解析庫lxml與xpath用法總結
    XPath 使用路徑表達式在 XML 文檔中進行導航 。XPath 包含一個標準函數庫 。XPath 是 XSLT 中的主要元素 。XPath 是一個 W3C 標準 。XPath 使用路徑表達式在 XML 文檔中選取節點。節點是通過沿著路徑或者 step 來選取的。下面列出了最有用的路徑表達式:表達式描述nodename選取此節點的所有子節點。/從根節點選取。//從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。.選取當前節點。..選取當前節點的父節點。@選取屬性。
  • Python爬蟲利器之Xpath語法與lxml庫的用法
    Rowling</author> <year>2005</year> <price>29.99</price></book></bookstore>選取節點XPath 使用路徑表達式在 XML 文檔中選取節點。節點是通過沿著路徑或者 step 來選取的。
  • xpath語法簡介
    除此之外,xpath表達式也是一種常見用法。xpath稱之為xml路徑語言,是一種基於xml的樹狀結構,來提取特定元素的語言。; html.xpath('/html')在xml的樹狀結構中,根節點用/表示,所有的元素都可以作為子節點存在。
  • 《前端5分鐘》之迭代器模式的N+1種應用場景
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫你將學到迭代器模式的含義實現一個數組迭代器>實現一個對象迭代器實現路徑查找/賦值迭代器如何用迭代器的思想解決分支循環嵌套問題實現一個圖片播放器正文
  • Dom4j的用法和XPath的使用
    Dom4j的基本用法element.element("stu"); 返回改元素下的第一個stu元素。element.elements(); 返回改元素下的所有子元素。創建SaxReader對象指定解析的xml獲取根元素根據根元素獲取子元素或者下面的子孫元素
  • Python爬蟲——Xpath和lxml
    Xpath 基本語法1.1什麼是XpathXpath,全稱 XML Path Language,及XML路徑語言,是一門在XML文檔中查找信息的語言,最初是用來搜尋XML文檔的,但是它同樣適用於HTML文檔的搜索。
  • 使用XPath語法與lxml模塊提取信息
    XPath (XML Path Language) 是一門在 XML 文檔中查找信息的語言,可用來在 XML 文檔中對元素和屬性進行遍歷。W3School官方文檔:http://www.w3school.com.cn/xpath/index.asp開源的XPath表達式編輯工具:XMLQuire(XML格式文件可用)Chrome插件 XPath HelperFirefox插件 Try XPath使用方式:1.使用//獲取整個頁面當中的元素,然後寫標籤,再寫謂詞進行提取
  • 「補課」進行時:設計模式(20)——解釋器模式
    解釋器模式 解釋器模式這個模式和前面的訪問者模式比較像,當然,我說的比較像是難的比較像,以及使用率是真的比較低,基本上沒有使用的場景,訪問者模式還有點使用場景,解釋器模式,我們又不寫解釋器,這玩意 JVM 都幫我們實現掉了,哪用我們自己實現。
  • 第64天:XPath 和 lxml
    XPath 和 lxml XPath 全稱為 Xml Path Language,即 Xml 路徑語言,是一種在 Xml 文檔中查找信息的語言。它提供了非常簡潔的路徑選擇表達式,幾乎所有的節點定位都可以用它來選擇。XPath 可以用於 Xml 和 Html,在爬蟲中經常使用 XPath 獲取 Html 文檔內容。
  • 答疑解惑丨進行Web自動化測試,為什麼總是定位不到元素?
    針對Robotframework和Selenium的安裝、使用等基礎知識不做介紹,只討論在進行自動化腳本編寫過程中遇到的元素定位失敗問題。 二、但是你不得不了解的事RF框架在做前端自動化時,支持的元素定位方式有:css定位、id定位、name定位、xpath定位和js定位。在介紹如何使用這幾種方法之前,你不得不認識並熟悉我們Web測試的基礎工具(客戶端)——瀏覽器。
  • 跟我快速學網絡爬蟲:網頁分析技術之XPath
    XPath用路徑來表示節點的位置,路徑中各層次之間使用符號「/」或「//」隔開。其中「/」表示根節點或者上一級直接的子節點,「//」表示上一級下任意的子節點。Python提供了lxml包來對HTML或者XML進行XPath操作,其中etree是包中較為常用的模塊,在代碼的頭部導入:【from lxml import etree】。
  • Xpath語法-網絡爬蟲基礎
    備註:此章節為基礎核心章節,未來會在網絡爬蟲的數據解析環節經常使用,學會Xpath解析語法,可為未來爬蟲解析省去很多麻煩。Xpath簡介XPath即為XML路徑語言,它是一種用來確定XML(標準通用標記語言的子集)文檔中某部分位置的語言。
  • Python 爬蟲必殺技:XPath
    因此,我們學習Python爬蟲,可以從使用XPath對XML進行定位開始~2.  當我們在程序中定位時,我們需要將這種表述轉換為路徑表達式,最常用的路徑表達式有:表達式含義/從根節點選取//從任意節點選取.選取當前節點..選取當前節點的父節點@選取屬性5.
  • Selenium自動化測試入門 獲取元素對象
    driver.find_element_by_xpath() # --- 最靈活,萬能的靈藥driver.find_element_by_css_selector() # --- 沒xpath靈活如果需要使用簡便的方法點位一組元素,在element後加個s,如,river.find_elements_by_id() ;它返回的也是 list列表。