Python爬蟲||Xpath-以豆瓣電視劇爲例

XPath——全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中查找信息的語言。它最初是用來搜尋XML文檔的,但是它同樣適用於HTML文檔的搜索。所以在爬蟲裏就可以直接使用Xpath來進行數據獲取,而且方法相較於正則表達式和bs4等要簡單很多。
工程中常用Python的lxml庫,利用XPath進行HTML的解析。

安裝庫

pip3 install lxml

導入

from lxml import etree

Xpath的常用規則

表達式 描述
nodename 選取此節點的所有子節點
/ 從當前節點選取直接子節點(絕對路徑)
// 從當前節點選取子孫節點(相對路徑)
. 選取當前節點
選取當前節點的父節點
@ 選取屬性

Xpath的基本語法

XPath 基礎表達式

表達式 描述
/node 表示在xml文檔的根目錄查找結點名稱爲node的結點
./node 表示在當前結點下查找結點名稱爲node的結點
//node 表示在xml文檔中遞歸查找結點名稱爲node的節點
//* 表示在xml文檔中查詢所有的結點,但是排除文本節點
//node() 表示在xml文檔中查詢所有結點,包含文本節點
//text() 表示在xml文檔中遞歸查找所有的文本節點
//*/text()[contains(., ‘test’)] 表示在xml文檔中遞歸查找所有結點,條件爲該結點的文本節點包含"test"
//node[@id] 表示在xml文檔中遞歸查找結點名稱爲node的結點,條件爲該結點必須含有id屬性
//node[id] 表示在xml文檔中遞歸查找結點名稱爲node的結點,條件爲該結點必須含有結點名稱爲id的結點
//nodes[node/id] 表示遞歸查找nodes結點,條件爲nodes結點下必須有node結點,且node結點下必須有id結點
//nodes[@id]/node[id] 表示遞歸查找含有id屬性的nodes結點下的node結點,條件爲node結點下必須含有id結點
//nodes[@id]/node[0] 表示遞歸查找含有id屬性的nodes結點下的第一個node結點
//nodes[@id]/node[last()] 表示遞歸查找含有id屬性的nodes結點下的最後一個node結點
//nodes/node[position() < 4] 表示遞歸查找nodes結點下索引小於4的node結點
//nodes[@id]/node[position() < last()] 遞歸查找含有id屬性的nodes結點下除最後一個結點外的node結點
/nodes/child::node()[name()=‘node’] 表示查找nodes結點下結點名稱爲node的子結點
/nodes/child::node 等同於/nodes/node表示查找nodes下的node子結點
/nodes/node/attribute::id 等同於/nodes/node/@id表示查找nodes結點下的node結點的id屬性
//nodes[@id=‘1001’]/node[starts-with(@id, ‘1’)] 表示查找id屬性爲1001的nodes結點下的id屬性以1開頭的node結點
//@*[ends-with(., ‘1’)] 表示查找以1結尾所有屬性
(//* //@*)[substring(name(), 1, 5) = ‘class’] 查找所有結點名稱或屬性名稱的1到5之間的字符等於’class’的結點
//node[@attr!=’-2’ and @attr!=‘2’] 查找所有node節點,其attr屬性不等於2和-2

XPath 文檔軸用途:

表達式 描述
self 選擇當前節點
parent 選擇當前節點的父節點
child 選擇當前節點的所有子節點
attribute 選擇當前節點的所有屬性
ancestor 選擇當前節點的所有祖先,包括父節點、父節點的父節點等等
ancestor-or-self 選擇當前節點的祖先以及當前節點本身
descendant 選擇當前節點的所有後代,包括子節點、子節點的子節點等等
descendant-or-self 選擇當前節點的後代以及當前節點本身
preceding 選擇整個文檔中出現在當前節點前面的所有節點
preceding-sibling 選擇文檔中出現在當前節點前面的所有同胞節點(即與當前節點同級的節點)
following 選擇整個文檔中出現在當前節點後面的所有節點
following-sibling 選擇文檔中出現在當前節點後面的所有同胞節點(即與當前節點同級的節點)
namespace 選擇當前節點的所有名稱空間節點

實例展示-豆瓣電視劇

豆瓣電視劇這個網頁比較特殊,是由動態頁面+靜態所組合的,可以看到在打開的初始網頁中有個“加載更多”的選項
在這裏插入圖片描述
哦吼,熟悉的動態網頁,那就要在網頁檢查中找到他的真正網址
在這裏插入圖片描述
通過網址我們找到了真正的網址信息,發現這一頁所有的電視劇信息都保存在Request URL後面的這個網址中,打開這個網址可以看到我們所需的詳細網址也在這個頁面中,即每一個電視劇的詳情頁,所以我們決定對該網址進行請求來獲取數據。
在這裏插入圖片描述
說那麼多其實用的就一點點,並且使用谷歌瀏覽器的童鞋可能已經發現了,右鍵在想獲取的信息上時,是可以直接copy所需信息的xpath,這。。不香嗎?
但是有的時候也會發現複製下來的xpath並不準確,或是獲取不到我們所需的完整信息,所以學習xpath對於爬蟲也是非常重要的。
話不多說,開始上代碼。

目標網址:https://movie.douban.com/tv
工具:Python3.7
環境:win10

import requests
import pandas as pd
from lxml import etree
import json

url='https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0'

#代理ip
proxies = {'http': '1.85.5.66',}

#設置headers
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36X-Requested-With: XMLHttpRequest'}
response=requests.get(url,headers=headers,proxies=proxies) #請求
print(response.status_code) #查看響應體,如果輸出200就表示網頁請求成功

response.encoding = 'utf-8'
html = response.json()  # 將json格式的字符串轉爲python數據類型
html1=html['subjects'] #數據存放在subjects中,所以將他提取出來

#每一個電視劇的詳細頁網址在subjects中,所以需要從subjects中將url提取出來
url=[]
for one in html1:
    url.append(one['url'])
print(url)

這樣就獲得了每個電視劇詳情頁的網址,這段代碼所得到的結果是這樣的:
在這裏插入圖片描述
可以看到採集到的詳情頁網址被保存在了列表裏,所以接下來就是對這些詳情頁進行請求獲取詳我們需要的細信息,也就要用到xpath的方法。

title=[]
jianj=[]
juqing=[]
otherlike=[]
fen=[]
watch=[]

for i in range(len(url)):
    res=requests.get(url[i],headers=headers,proxies=proxies)
    html = etree.HTML(res.text)
    title.append(''.join(html.xpath('//*[@id="content"]/h1/span/text()')))
    jianj.append(''.join(html.xpath('//*[@id="info"]/span/text()')))
    juqing.append(''.join(html.xpath('//*[@id="link-report"]/span/text()')))
    otherlike.append(''.join(html.xpath('//*[@id="recommendations"]/div/dl/dd/a/text()')))
    fen.append(''.join(html.xpath('//*[@id="interest_sectl"]/div/div[2]/strong/text()')))
    watch.append(''.join(html.xpath('//*[@id="content"]/div[2]/div[2]/div[1]/ul/li/a/text()')))
    
columns={'劇名':title,'簡介':jianj,'劇情':juqing,'還喜歡':otherlike,'評分':fen,'觀看':watch}
df=pd.DataFrame(columns)
df.head()

得到的數據如下:
在這裏插入圖片描述
Xpath應該是我目前用到的最簡單的爬蟲方法了,如果以後遇到更簡單的再繼續和大家分享哦O(∩_∩)O

注:本次抓取數據僅作學習研究之用

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