五:爬蟲-數據解析之xpath解析

三:數據解析之xpath解析

1.xpath介紹:
  • ? xpathXML路徑語言,它可以用來確定xml文檔中的元素位置,通過元素路徑來完成對元素的查找,HTML就是XML的一種實現方式,所以xpath是一種非常強大的定位方式
  • ? XPathXML Path Language)是一種XML的查詢語言,它能在XML樹狀圖中尋找節點。XPath用于在XML文檔中通過元素和屬性進行導航
  • ? xml是一種標記語法的文本格式,xpath可以方便的定位xml中的元素和其中的屬性值。lxml是Python中的一個第三方模塊,它包含了將html文本轉成xml對象,和對對象執行xpath的功能

lxml的安裝:

#在終端輸入
pip install lxml

xpath的弊端:

? 當我們在批量獲取數據的時候,如果存在的特別數據比較多,這個時候只用xpath的話,會無法滿足用戶的需求,所以針對于不同的網頁,我們要靈活的去運用我們的數據解析方式

(1)HTML樹狀結構圖:

在這里插入圖片描述

? HTML 的結構就是樹形結構,HTML 是根節點,所有的其它元素節點都是從根節點發出的,其它的元素都是這棵樹上的節點,每個節點還可能有屬性和文本值,而路徑就是指某個節點到另一個節點的路線

(2)節點之間的關系:

  • ? 父節點:HTML 是 body 和 head 節點的父節點
  • ? 子節點:headbodyHTML 的子節點
  • ? 兄弟節點:擁有相同的父節點,headbody 就是兄弟節點,titlediv 不是兄弟,因為他們不是同一個父節點
  • ? 祖先節點:bodyform 的祖先節點,爺爺輩及以上
  • ? 后代節點:formHTML 的后代節點,孫子輩及以下
2.Xpath中的絕對路徑與相對路徑 :

? Xpath中的絕對路徑是從HTML根節點開始算的;而相對路徑(使用的更多)則是從任意節點開始的。通過開發者工具,我們可以拷貝到Xpath的絕對路徑和相對路徑代碼:

在這里插入圖片描述

? 注意: 絕對路徑是以 Elements 為基準去尋找的,我們爬蟲獲取的是右鍵的網頁源代碼;右鍵的網頁源代碼 != ElementsElements 是前端頁面最終渲染的結果,它與網頁源代碼是有屬性上的差異的;但右鍵的網頁源代碼與Elements是非常相似的,但是在某些元素或者元素屬性上會存在不同。這就會導致我們直接右鍵復制的xpath獲取不到真正的數據;所以說只能手寫,不能復制(把數據解析全部學會之后,可以復制,因為到那個時候就有能力對復制到的內容進行微調了)

(1)絕對路徑(了解即可):

? 在Xpath中最直觀的定位策略就是絕對路徑,絕對路徑是從根節點/html開始往下一層層的表示,直到出來需要的節點為止

(2)相對路徑(常用):

? 在Xpath中相對路徑方法以 “//” 開頭,相對路徑可以從任意的節點開始,一般會選取一個可以唯一定位到的元素開始寫,這樣可以增加查找的準確性

相對路徑的定位語法:

(1)基本定位語法:

表達式說明舉例
/從根節點開始選取/html/div/span
//從任意節點開始選取//input
.選取當前節點
..選取當前節點的父節點//input/.. 選取input的父節點
@選取屬性或者根據屬性選取//input[@data]選取具備data屬性的input元素 //@data 選取所有data屬性
*通配符,表示任意節點或任意屬性

(2)元素屬性定位:

在這里插入圖片描述

(3)層級屬性結合定位:

? 遇到某些元素無法精確定位的時候,可以查找其父級及其祖先節點,找到有確定的祖先節點后通過層級依次向下定位

示例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="search" id="form" method="post"><span class="bg"><span class="soutu">搜索</span></span><span class="soutu"><input type="text" name="key" id="su"></span><div></div>
</form>
</body>
</html>

圖片解析:

在這里插入圖片描述

(4)使用謂語定位:

? 謂語是Xpath中用于描述元素位置,主要有數字下標、最后一個子元素last()、元素下標函數position()

? 注意: Xpath中的下標從 1 開始

圖片解析:

在這里插入圖片描述

1、使用下標的方式,從form找到input:
//form[@id="form"]/span[2]/input2、查找最后一個子元素,選取form下的最后一個span:
//form[@id="form"]/span[last()]3、查找倒數第幾個子元素,選取 form下的倒數第二個span:
//form[@id="form"]/span[last()-1]4、使用 position() 函數,選取 from 下第二個span:
//form[@id="form"]/span[position()=2]5、使用 position() 函數,選取下標大于 2 的span:
//form[@id="form"]/span[position()>2]

(5)使用邏輯運算符定位:

? 用于嵌套的標簽,如果元素的某個屬性無法精確定位到這個元素,還可以用邏輯運算符and連接多個屬性進行定位

以百度首頁為例:

使用and:
//*[@name='wd' and @class='s_ipt']
#查找 name 屬性為 wd 并且 class 屬性為 s_ipt 的任意元素使用or:
//*[@name='wd' or @class='s_ipt']
#查找 name 屬性為 wd 或者 class 屬性為 s_ipt 的任意元素,取其中之一滿足即可

以上述示例代碼為例:

使用|同時查找多個路徑,取或:
//form[@id="form"]//span | //form[@id="form"]//input

(6)使用文本定位:

? 我們在爬取網站使用Xpath提取數據的時候,最常使用的就是Xpathtext()方法,該方法可以提取當前元素的信息,但是某些元素下包含很多嵌套元素,這時候就用到了string()方法

爬取別逗了網站示例代碼:

import requests
from lxml import etreeurl = 'https://www.biedoul.com/article/180839'headers= {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
}response = requests.get(url,headers=headers)
response.encoding = 'utf-8'  # 在requests.get的時候,會默認指定一個編碼,但默認指定的編碼不一定會是utf-8,是隨機的# 將獲取的網頁源代碼html文件轉換成xml對象,方便后續執行xpath語法
html = etree.HTML(response.text)
data = html.xpath('//div[@class="cc2"]//text()')  # //text()指的是取標簽中的文本值,不是屬性值
# print(data)
#
# data = [i.replace('\r\n','') for i in data]
# print('\n'.join(data))data1 = html.xpath('//div[@class="cc2"]')[0].xpath('string(.)')
print(data1)

? 注意: xpath對象獲取的數據返回的是一個列表

(7)使用部分匹配函數:

函數說明示例
contains選取屬性或者文本包含某些字符//div[contains(@id, 'data')]選取id屬性包含datadiv元素
starts-with選取屬性或者文本以某些字符開頭//div[starts-with(@id, 'data')]選取id屬性以data開頭的div元素
ends-with選取屬性或者文本以某些字符結尾//div[ends-with(@id, 'require')]選取id屬性以require結尾的div元素
3.lxml的使用與xpath實戰:

(1)lxml的基本使用:

# 導入模塊
from lxml import etree
# html源代碼
web_data = """<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul></div>"""
# 將html轉成xml對象
element = etree.HTML(web_data)
# print(element)
# 獲取li標簽下面的a標簽的href
links = element.xpath('//ul/li/a/@href')
print(links)  # 列表
# 獲取li標簽下面的a標簽的文本數據
result = element.xpath('//ul/li/a/text()')
print(result)

(2)xpath實戰 – 豆瓣top250示例代碼:

import requests
from lxml import etree
'''
目標:熟悉xpath解析數的方式
需求:爬取電影的名稱 評分 引言 詳情頁的url  翻頁爬取1-10頁 保存到列表中如何實現?
設計技術與需要的庫 requests lxml(etree)實現步驟
1 頁面分析(一般講數據解析模塊 都是靜態頁面)1.1 通過觀察看網頁源代碼中是否有我們想要的數據 如果有就分析這個url如果沒有再通過ajax尋找接口   通過分析數據在網頁源代碼中1.2 確定目標urlhttps://movie.douban.com/top250?start=0&filter= 第一頁通過頁面分析發現所有我們想要的數據都在一個div[class="info"]里面具體實現步驟
1 獲取整個網頁的源碼 html
2 將獲取的數據源碼轉成一個element對象(xml)
3 通過element對象實現xpath語法 對數據進行爬取(標題 評分 引言 詳情頁的url)
4 保存數據  先保存到字典中-->列表中'''# 定義一個函數用來獲取網頁源代碼
def getsource(pagelink):# 請求頭headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'}# 獲取源碼response = requests.get(pagelink, headers=headers)response.encoding = 'utf-8'html = response.textreturn html# 定義一個函數用于解析我們的網頁源代碼并獲取我們想要的數據
def geteveryitem(html):element = etree.HTML(html)# 拿到[class="info"]的所有divmovieitemlist = element.xpath('//li//div[@class="info"]')# print(movieitemlist,len(movieitemlist))# 定義一個列表itemlist = []for item in movieitemlist:# 定義一個字典itemdict = {}# 標題title = item.xpath('./div[@class="hd"]/a/span[@class="title"]/text()')title = "".join(title).replace("\xa0", "")# print(title)# 副標題othertitle = item.xpath('./div[@class="hd"]/a/span[@class="other"]/text()')[0].replace("\xa0", "")# print(othertitle)# 評分grade = item.xpath('./div[@class="bd"]/div[@class="star"]/span[2]/text()')[0]# print(grade)# 詳情頁的urllink = item.xpath('div[@class="hd"]/a/@href')[0]# print(link)# 引言quote = item.xpath('div[@class="bd"]/p[@class="quote"]/span/text()')# print(quote)# list index out of range# 處理方式1 非空處理if quote:quote = quote[0]else:quote = ""# 將數據存放到字典中itemdict['title'] = ''.join(title + othertitle)itemdict['grade'] = gradeitemdict['link'] = linkitemdict['quote'] = quote# print(itemdict)itemlist.append(itemdict)# print(itemlist)return itemlistif __name__ == '__main__':url = 'https://movie.douban.com/top250?start=0&filter='html = getsource(url)itemlist = geteveryitem(html)print(itemlist)
dict['quote'] = quote# print(itemdict)itemlist.append(itemdict)# print(itemlist)return itemlistif __name__ == '__main__':url = 'https://movie.douban.com/top250?start=0&filter='html = getsource(url)itemlist = geteveryitem(html)print(itemlist)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/214095.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/214095.shtml
英文地址,請注明出處:http://en.pswp.cn/news/214095.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue2 element-ui select下拉框 選擇傳遞多個參數

<el-select v-model"select" slot"prepend" placeholder"請選擇" change"searchPostFn($event,123)"> <el-option :label"item.ziDianShuJu" :value"{value:item.id, label:item.ziDianShuJu}" v-for&qu…

Ubuntu系統使用快速入門實踐(七)——軟件安裝與使用(5)

Ubuntu系統使用快速入門實踐系列文章 下面是Ubuntu系統使用系列文章的總鏈接&#xff0c;本人發表這個系列的文章鏈接均收錄于此 Ubuntu系統使用快速入門實踐系列文章總鏈接 下面是專欄地址&#xff1a; Ubuntu系統使用快速入門實踐系列文章專欄 文章目錄 Ubuntu系統使用快速…

crypto-js加密、解密與node Crypto加解密模塊的應用

前端用crypto-js實現加解密&#xff0c;node端用Crypto模塊&#xff0c;兩者想要相同結果的話&#xff0c;就要保持加密密鑰和加密算法一致。 crypto-js加密、解密 參考&#xff1a; 『crypto-js 加密和解密』 前端使用CryptoJS加密解密 // DES算法 import CryptoJS from cryp…

【unity】【WebRTC】從0開始創建一個Unity遠程媒體流app-構建可同步場景

【背景】 最近在研究遠程畫面&#xff0c;所以就實踐了一下。技術采用我認為比較合適的WebRTC。 這篇文章的基礎是我的另一篇博文&#xff0c;如果希望順利完成本篇操作&#xff0c;請先關注我后查詢我的如下博文&#xff1a; 【WebRTC】【Unity】Unity Web RTC1-Unity中簡單實…

Docker架構及常用的命令

一、初識Docker 1、 docker是一個快速交付應用、運行應用的技術&#xff0c;具備下列優勢&#xff1a; 可以將程序及其依賴、運行環境一起打包為一個鏡像&#xff0c;可以遷移到任意Linux操作系統運行時利用沙箱機制形成隔離容器&#xff0c;各個應用互不干擾啟動、移除都可以…

邊緣智能網關如何應對環境污染難題

隨著我國工業化、城鎮化的深入推進&#xff0c;包括大氣污染在內的環境污染防治壓力繼續加大。為應對環境污染防治難題&#xff0c;佰馬綜合邊緣計算、物聯網、智能感知等技術&#xff0c;基于邊緣智能網關打造環境污染實時監測、預警及智能干預方案&#xff0c;可應用于大氣保…

銀行數據分析入門篇:信用卡全生命周期分析,到底應該怎么做?

最近有朋友向我咨詢銀行信貸業務的數據分析&#xff0c;就看了很多案例&#xff0c;剛好看到一個信用卡全生命周期分析的案例&#xff0c;做得很詳細又通俗易懂&#xff0c;基本上可以直接復制套用&#xff0c;所以特地分享給大家。 本文主要分享作者整個分析作品的思路&#x…

Unity對象池

標題&#xff1a;Unity對象池技術詳解 一、引言 在Unity游戲開發中&#xff0c;我們經常需要創建大量的游戲對象&#xff0c;如子彈、敵人和道具等。然而&#xff0c;頻繁地創建和銷毀這些對象會消耗大量的系統資源&#xff0c;影響游戲的性能。為了解決這個問題&#xff0c;…

golang 使用 viper 加載配置文件 自動反序列化到結構

golang使用 viper 無需設置 mapstructure tag 根據配置文件后綴 自動返序列化到結構 解決結構有下劃線的字段解析不成功問題 viper 正常加載配置文件 golang viper 其中可以用來 查找、加載和反序列化JSON、TOML、YAML、HCL、INI、envfile和格式的配置文件 配置文件 test_to…

jdom利用純java技術對xml文檔進行解析、生成、序列化等各種操作

Jdom對xml文檔進行解析、生成、序列化等各種操作。 使用jdom之前&#xff0c;首先要導入jar包&#xff1a;jdom.jar 獲得根元素&#xff1a; //首先確定xml文件位置 String xmlPath "./src/ceshi/Test.xml"; //使用的解析器&#xff0c;這里表示默認的解…

KMP算法數組下標從0和數組下標從1開始

我在運用KMP時&#xff0c;總時會搞混如果數組下標為0時要如何用寫&#xff0c;下標為1時要如何寫。 當下標為0時kmp void kmp(int len) {//下標為0 時vector<int> f(n,-1);for(int i 1;i < len;i){ // 每次更新的是 下標i // 當第 i1不匹配是 跳到 f[i]的位置上&…

106.進程控制(結束、孤兒、僵尸進程)以及進程回收

目錄 結束進程 孤兒進程 僵尸進程 進程回收 wait() waitpid 進程控制是指在操作系統中對進程進行創建、終止、掛起、喚醒以及進程之間的同步、通信等操作的管理。 結束進程 exit() 和 _exit() 函數都用于終止一個進程&#xff0c;但它們之間有一些重要的區別&#xf…

新工科:數據科學與大數據技術實驗中心解決方案,賦能高校新工科數智人才培養

隨著數字經濟蓬勃發展&#xff0c;數字化產業和產業數字化成為就業增長新動能。據人瑞人才與德勤調研顯示&#xff0c;未來3年&#xff0c;數字產業化企業最需要運營人員和開發人員&#xff08;包括大數據開發工程師、數據建模開發工程師等&#xff09;&#xff0c;其次是數據分…

【RTOS學習】FreeRTOS中的鏈表 | 堆的管理

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;專欄&#xff1a;《RTOS學習》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交給時間&#xff01; 目錄 &#x1f969;FreeRTOS中的鏈表&#x1f95e;初始化&#x1f95e;尾部插入&#x1f95e;按順…

OpenWRT搭建本地web站點并結合內網穿透實現公網遠程訪問

文章目錄 前言1. 檢查uhttpd安裝2. 部署web站點3. 安裝cpolar內網穿透4. 配置遠程訪問地址5. 配置固定遠程地址 前言 uhttpd 是 OpenWrt/LuCI 開發者從零開始編寫的 Web 服務器&#xff0c;目的是成為優秀穩定的、適合嵌入式設備的輕量級任務的 HTTP 服務器&#xff0c;并且和…

【Windows】MCSM面板搭建Mycraft服務器,實現公網遠程聯機

文章目錄 前言1.Mcsmanager安裝2.創建Minecraft服務器3.本地測試聯機4. 內網穿透4.1 安裝cpolar內網穿透4.2 創建隧道映射內網端口 5.遠程聯機測試6. 配置固定遠程聯機端口地址6.1 保留一個固定TCP地址6.2 配置固定TCP地址 7. 使用固定公網地址遠程聯機 前言 MCSManager是一個…

[香橙派]Orange pi zero 3命令行配網方法——建立ssh連接——Ubuntu配置WIFI自動連接

一、前言 前面我們給Orange Pi安裝了Ubuntu系統&#xff0c;并通過MobaXterm進行了串口連接&#xff0c;但其實并不方便&#xff0c;在日常開發中&#xff0c;我們希望能夠使用更方便的ssh連接來進行操作&#xff0c;因此配置網絡是必要的。 本章介紹的方法無需網線、HDMI線等&…

upload-labs

01 隨便上傳個文件 發現對于上傳類型有限制 查看頁面代碼發現是js的過濾直接關閉js 上傳成功 右鍵圖片在新建標簽頁打開文件 這里直接抓包改名字也行 02 抓包修改后綴名 03 發現后端做了檢測抓包修改失敗 大小寫繞過失敗&#xff0c;php特性php1等會被當成php執行 這里圖片的…

私域流量:探索營銷新紀元的高效之路

在當前的數字營銷領域&#xff0c;私域流量已經嶄露頭角&#xff0c;成為企業和品牌爭相追逐的新路徑。私域流量指的是企業或品牌通過自有渠道&#xff0c;如網站、APP、微信公眾號等&#xff0c;直接觸達的用戶流量。這種流量具有更高的自主性和可控性&#xff0c;對于提升營銷…

MS1242,替代ADS1242,24bit 高精度、低功耗模數轉換器

產品簡述 MS1242/MS1243 是一款高精度、寬動態范圍、 ?-Σ 模數轉 換芯片&#xff0c;其工作電壓為 2.7V 至 5.25V &#xff0c;可以達到 24bit 無失碼轉 換&#xff0c;有效精度可達 21bit 。 MS1242/MS1243 可以廣泛使用在工 業控制、稱重、液體 / 氣體化學分析、血液分…