第三章 lxml與xpath:體力活

在這裏插入圖片描述

環境

Python 3.6.5

Pycharm Professional 2017.1

需要預備的知識

第二章內容

簡介

當你通過一些模擬請求手段,並且有幸突破了反爬,拿到了包含正確數據的請求結果,而且結果的格式是html,那麼就該xpath上場了。

xpath是一種路徑表達式,利用一定的規則在xml/html中查找信息。

lxml 是一個html/xml的解析器,主要的功能是解析和提取html/xml數據。lxml和正則一樣,也是用C實現的,是一款高性能的python html/xml解析器,可以利用xpath語法,來快速的定位特定元素以及節點信息。

lxml python 官方文檔:http://lxml.de/index.html

安裝

在pycharm的terminal終端命令窗口中輸入:
pip install lxml
或者使用清華源的鏡像,會更快一點
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml

知識

個人使用體驗,lxml這個工具,就是把html/xml處理爲類似dom的樹形結構,然後基於樹的層次結構(即xpath路徑表達式),迅速定位特定節點,然後從節點獲取屬性或者信息(這裏的節點指的就是html的一個個標籤)。

所以使用lxml分爲兩步:

  1. 使用lxml將html這個超大字符串進行初始化(固定不變的,而且這個字符串必須符合html的規範,這個需要注意,不然有些小夥伴有時候不關注返回結果類型,強行使用lxml與xpath)
  2. 使用xpath表達式,提取lxml構造的”dom“中的信息

第一步初始化

# 導入剛安裝好的輪子
from lxml import etree

# 加載Html字符串 
root = etree.HTML(html)
#如果是文件 換成parse(path)
# root = etree.parse(path)

print(root)
print(type(root))
print(etree.tostring(root))

etree.HTML函數所需的字符串,就是之前requests獲取的結果,這樣串起來就是這樣的結構:

import requests
from lxml import etree

# 獲取應答對象
response = requests.get(url)
# 提取響應信息
html_str = response.content.decode()
# 對html字符串進行初始化
root = etree.HTML(html_str)

第二步xpath路徑表達式提取信息

我們拿一個簡單的html字符串進行

html_str = """
<html>
	<head>
		<title>xpath學習</title>
	</head>
	<body>
		<ul>
			<li id="l1">
				<h3 class="title" href="https://www.huawei.com/cn/">華爲</h3>
				<p class="price">5000</p>
			</li>
			<li id="l2">
				<h3 class="title" href="https://www.mi.com/">小米</h3>
				<p class="price">3000</p>
			</li>
			<li id="l3">
				<h3 class="title">藍綠</h3>
				<p class="price">4000</p>
			</li>
		</ul>
		<div>
			<li id="l4">
				<h3 class="xxx">蘋果</h3>
				<p class="price">10000</p>
			</li>
		</div>
		<div>
			<li id="l5">
				<h3 class="xxx">諾基亞</h3>
				<p class="price">2000</p>
			</li>
		</div>
	</body>
</html>"""

選取節點

表達式 描述
/ 從當前節點尋找下一層節點
// 從當前節點尋找所有節點,不考慮層級
. 選取當前節點
選取當前節點的父節點
@. 選取節點屬性
text() 選取節點的*innerHTML*文本

看到 ‘/’,‘//’,‘.’,‘…’ 這些符號不知道大家能想到什麼,對了那就是IO、文件。大家可以把xpath想象成我們在文件資源管理查找文件。文件資源管理器本身也是一個樹形結構,你可以使用C:\Users\LFF\Desktop\text.txt這種類似的路徑找到你想找的文件。

# 構建DOM
root = etree.HTML(html_str )
# 使用路徑表達式取數據
#  . 取當前節點 如果只是單獨一個點的話訪問的爲根節點
result = root.xpath(".")
#  / 取子節點
result = root.xpath("/html/head/title")
# // 不考慮位置 只要標籤名一致 全部取出 
result = root.xpath("//h3")
# .. 返回當前標籤的上一級標籤
result = root.xpath("//p/..")
# @ 取標籤裏邊的屬性 (返回類型以及是etree._ElementUnicodeResult,上面的表達式最後一層不是@屬性或者text()的返回值都爲etree._Element)
result = root.xpath("//ul/li/h3/@href")
# text() 取標籤裏邊的innerHTML (屬於字符串信息 不屬於元素)
result = root.xpath("//h3/text()")


#  打印xpath結果信息
for item in result:
    # 
    if type(item) == etree._ElementUnicodeResult:
        print(item)
    else:
        print(etree.tostring(item))

帶條件的選擇節點

主要分爲兩種方式,一種是按節點的位置進行過濾,一種是按節點是否包含特定的屬性進行過濾

表達式 描述
//h3[3] 選取第三個h3標籤,類似索引,不過是從1開始
//h3[last()] 取最後一個h3標籤,這裏不是用的-1
//h3[last()-1] 取倒數第二個h3標籤,這裏按位置篩選,類似索引的寫法支持加減法
//h3[position() < 3] 取位置小於3的h3標籤,即第一個和第二個h3標籤
//h3[@href] 選取所有擁有href屬性的h3標籤
//h3[@class=“title”] 選取所有擁有class屬性且class屬性爲title的h3標籤
root = etree.HTML(html_str)
# 按照位置進行過濾
result = root.xpath("//h3")
result = root.xpath("//h3[last()]")
result = root.xpath("//h3[last()-1]")
result = root.xpath("//h3[position()<3]")
# 按照屬性進行過濾
result = root.xpath("//h3[@href]")
result = root.xpath(" //h3[@class='title']")
# 取出text,查看xpath選取結果
for item in result:
    # result獲取的符合條件的h3標籤,item此時指的就是h3標籤
    # .表示的就是h3標籤,從h3標籤往下選擇裏邊的文本
    print(item.xpath("./text()"))

其他選取方式

表達式 描述
//li/* 選取所有li下邊的子標籤
//h3 | //p 同時選取所有h3標籤和p標籤
//節點名字[contains(@屬性名/text(),“子字符串”)] 選取屬性包含某個字符串的標籤
starts-wiith(@屬性名/text(),"子字符串“) 選取屬性以某個字符串開頭的標籤

xpath瀏覽器輔助分析插件

火狐:
頁面xpath測試插件:TryXpath
頁面xpath智能提示插件:TruePath

谷歌:
頁面xpath測試插件:ChroXpath
頁面xpath測試插件:Xpath Helper

但這些插件給出的xpath路徑表達式只供參考,一般情況下,需要修改才能在程序中使用。

任務

51job自己感興趣的崗位信息
https://search.51job.com/list/020000,000000,0000,00,9,01,%25E7%2588%25AC%25E8%2599%25AB,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=
在這裏插入圖片描述

貼吧信息
http://tieba.baidu.com/f?ie=utf-8&kw=%E7%AC%94%E8%AE%B0%E6%9C%AC&fr=search&red_tag=b3364292370
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章