爬蟲系列(九) xpath的基本使用


一、xpath 簡介

究竟什么是 xpath 呢?簡單來說,xpath 就是一種在 XML 文檔中查找信息的語言

而 XML 文檔就是由一系列節點構成的樹,例如,下面是一份簡單的 XML 文檔:

<html>
	<body>
		<div>
			<p>Hello world<p>
			<a href="/home">Click here</a>
		</div>
	</body>
</html>

XML 文檔中常見的節點包括:

  • 根節點:html
  • 元素節點:html、body、div、p、a
  • 屬性節點:href
  • 文本節點:Hello world、Click here

XML 文檔中常見的節點間關系包括:

  • 父子:例如,<p> 和 <a> 是 <div> 的子節點,反之,也稱 <div> 是 <p> 和 <a> 的父節點
  • 兄弟:例如,<p> 和 <a> 稱為兄弟節點
  • 祖先/后代:例如,<body>、<div>、<p>、<a> 都是 <html> 的后代節點,反之,也稱 <html> 是 <body>、<div>、<p>、<a> 的祖先節點

對於網頁解析來說,xpath 比 re 更加方便簡潔,故 Python 中也提供相應的模塊 —— lxml.etree

我們可以使用 pip install lxml 命令進行安裝

二、xpath 使用

在正式開始講解 xpath 的使用方法之前,我們先來構造一個簡單的 XML 文檔用於測試

在一般的爬蟲程序中,XML 文檔就是爬取回來的網頁源代碼

>>> sc = '''
<html>
	<head>
    	<meta charset="UTF-8"/>
		<link rel="stylesheet" href="style/base.css"/>
		<title>Example website</title>
	</head>
	<body>
		<div id="images" class="content">
			<a href="image1.html">Image1<img src="image1.jpg"/></a>
			<a href="image2.html">Image2<img src="image2.jpg"/></a>
			<a href="image3.html">Image3<img src="image3.jpg"/></a>
		</div>
	</body>
</html>
'''

1、導入模塊

>>> from lxml import etree

2、構造對象

>>> html = etree.HTML(sc) # 構造 lxml.etree._Element 對象
>>> # lxml.etree._Element 對象還具有代碼補全功能
>>> # 假如我們得到的 XML 文檔不是規范的文檔,該對象將會自動補全缺失的閉合標簽
>>> # 我們可以使用 tostring() 方法將對象轉化成 bytes 類型的字符串
>>> # 再使用 decode('utf-8') 方法將 bytes 類型的字符串轉化為 str 類型的字符串
>>> print(etree.tostring(html).decode('utf-8'))

3、匹配數據

我們可以使用 xpath() 方法進行匹配

(1)xpath 匹配語法

xpath 方法接受一個滿足 xpath 匹配語法的字符串作為參數

下面主要介紹一下 xpath 匹配語法:

  • / 表示子代節點,例如 /E 表示匹配根節點下的子節點中的 E 元素節點

    >>> test = html.xpath('/html/head/title')
    
  • // 表示后代節點,例如 //E 表示匹配根節點下的后代節點中的 E 元素節點

    >>> test = html.xpath('//a')
    
  • * 表示所有節點,例如 E/* 表示匹配 E 元素節點下的子節點中的所有節點

    >>> test = html.xpath('/html/*')
    
  • text() 表示文本節點,例如 E/text() 表示匹配 E 元素節點下的子節點中的文本節點

    >>> test = html.xpath('/html/head/title/text()')
    
  • @ATTR 表示屬性節點,例如 E/@ATTR 表示匹配 E 元素節點下的子節點中的 ATTR 屬性節點

    >>> test = html.xpath('//a/@href')
    
  • 謂語 用於匹配指定的標簽

    • 指定第二個 <a> 標簽

      >>> test = html.xpath('//a[2]')
      
    • 指定前兩個 <a> 標簽

      >>> test = html.xpath('//a[position()<=2]')
      
    • 指定帶有 href 屬性的 <a> 標簽

      >>> test = html.xpath('//a[@href]')
      
    • 指定帶有 href 屬性且值為 image1.html 的 <a> 標簽

      >>> test = html.xpath('//a[@href="image1.html"]')
      
    • 指定帶有 href 屬性且值包含 image 的 <a> 標簽

      >>> test = html.xpath('//a[contains(@href,"image")]')
      

(2)_Element 對象

xpath 方法返回字符串或者匹配列表,匹配列表中的每一項都是 lxml.etree._Element 對象

下面主要介紹一下 _Element 對象的常用屬性與方法:

我們先用 xpath 方法得到匹配列表 tests 作為測試樣例,tests 中的每一項都是一個 _Element 對象

>>> test = html.xpath('//a[@href="image1.html"]')
>>> obj = test[0]
  • tag 返回標簽名
>>> obj.tag
'a'
  • attrib 返回屬性與值組成的字典
>>> obj.attrib
{'href': 'image1.html'}
  • get() 返回指定屬性的值
>>> obj.get('href')
'image1.html'
  • text 返回文本值
>>> obj.text
'Image1'

【參考資料】

【爬蟲系列相關文章】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM