關于xpath的具體教程可以看崔大神的這篇:https://cuiqingcai.com/2621.html
- 安裝lxml:pip install lxml
- 路徑表達式
表達式 | 描述 |
---|---|
nodename | 選取此節(jié)點的所有子節(jié)點 |
/ | 從根節(jié)點選取 |
// | 從匹配選擇的當前節(jié)點選擇文檔中的節(jié)點院崇,而不考慮它們的位置 |
. | 選取當前節(jié)點 |
.. | 選取當前節(jié)點的父節(jié)點 |
@ | 選取屬性 |
實例代碼:
from lxml import etree
text = """
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=7,9,10,11"/>
<meta name="renderer" content="webkit">
<title>Title</title>
</head>
<body>
<div class="catalog-list column-3">
<ol>
<li class="level1">
<span class="index">1</span>
<span class="text"><a href="#1">簡介</a></span>
</li>
<li class="level1">
<span class="index">2</span>
<span class="text"><a href="#2">語法</a></span>
</li>
<li class="level1">
<span class="index">3</span>
<span class="text"><a href="#3">表達式</a></span>
</li>
<li class="level2">
<span class="index">4</span>
<span class="text"><a href="#4">運算符</a></span>
</li>
</ol><ol><li class="level1">
<span class="index">5</span>
<span class="text"><a href="#5">標準函數</a></span>
</li>
<li class="level3">
<span class="index">6</span>
<span class="text"><a href="#6">使用</a></span>
</li>
<li class="level1">
<span class="index">7</span>
<span class="text"><a href="#7">標準</a></span>
</li>
<li class="level1">
<span class="index">8</span>
<span class="text"><a href="#8">軸定義</a></span>
</li>
</ol><ol><li class="level4">
<span class="index">9</span>
<span class="text"><a href="#9">節(jié)點關系</a></span>
</li>
<li class="level4">
<span class="index">10</span>
<span class="text"><a href="#10">存取函數</a></span>
</li>
<li class="level4">
<span class="index">11</span>
<span class="text"><a href="#11">語言升級</a></span>
</li>
<li class="level4">
<span class="index">12</span>
<span class="text"><a href="#12">實例</a></span>
</li>
</ol>
<ol>
<li>A</li>
<li>A</li>
<li>A</li>
</ol>
</div>
</body>
</html>
"""
# 數據初始化
data = etree.HTML(text)
# 打印初始化的數據
result = etree.tostring(data)
print(result)
# 根據標簽名稱選取此節(jié)點理朋,如body等
result = data.xpath('body')
# / 從根節(jié)點選取
result = data.xpath('/html/head/meta')
# // 從匹配選擇的當前節(jié)點選擇文檔中的節(jié)點堕战,而不考慮它們的位置帜消。
# 獲取所有的<ol>標簽
result = data.xpath('//ol')
# . 選取當前節(jié)點
# 選取當前result下的<li>標簽
li = result[0].xpath('./li')
# @ 選取屬性
# 獲取 <li> 標簽的所有 class
result = data.xpath('//li/@class')
print(result)
# 獲取所有<a>標簽的href值
result = data.xpath('//a/@href')
print(result)
# 獲取 <li> 標簽下 href 為 #7 的 <a> 標簽
result = data.xpath('//li//a[@href="#7"]')
# 獲取 <li> 標簽下的所有 <a> 標簽
result = data.xpath('//li//a') #<a> 并不是 <li> 的子元素描孟,所以鳞溉,要用雙斜杠
CSDN實例
import requests
from lxml import etree
import json
# 爬取CSDN論壇信息的類
class BBSpider:
url = "https://bbs.csdn.net/tech_hot_topics"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
# 存放最終的數據恍风,用于數據存儲
result_list = []
# 根據給到的url獲取網頁數據并返回
def get_data(self, url):
r = requests.get(url=url, headers=self.headers)
data = r.text
return data
# 解析得到的網頁數據堪簿,分析出該頁的帖子的時間棒旗、帖子標題喘批、帖子鏈接
def parse_data(self, data, url):
# 將網頁的數據進行轉化
html = etree.HTML(data)
if data is not None:
# 帖子內容都在class="list_1"的div標簽中,在無序列表ul铣揉,以li標簽的形式進行展示
div = html.xpath('//div[@class="list_1"]//li')
# 遍歷每個li標簽饶深,獲取li標簽中包含的時間time、帖子標題content逛拱、帖子鏈接link
for tiezi in div:
dict = {}
# 獲取li標簽中包含的時間time
dict['time'] = tiezi.xpath('./span/text()')[0]
# 獲取li標簽中包含的帖子標題content
dict['content'] = tiezi.xpath('./a/text()')[0]
# 獲取li標簽中包含的帖子鏈接link
dict['link'] = 'https://bbs.csdn.net' + tiezi.xpath('./a/@href')[0]
# 將獲取到的帖子信息存放到類成員變量result_list中敌厘,便于后續(xù)的數據保存
self.result_list.append(dict)
else:
print("NO Data: "+url)
# 存儲數據,將result_list中的數據以json的格式保存到data.json文件中
def save_data(self):
data = json.dumps(self.result_list)
with open("data.json", "w") as f:
f.write(data)
# 由于CSDN的論壇是以翻頁的形式進行展示的朽合,翻頁的鏈接為:域名+"?page=xxx",以下是對每一頁的數據進行數據的獲取俱两、解析,最后保存的操作
def run(self):
# 獲取從第1頁到第9頁的數據
for i in range(1,10):
url = self.url + "?page="+str(i)
data = self.get_data(url)
self.parse_data(data, url)
print(len(self.result_list))
# 保存第1頁到第9頁全部的網頁數據
self.save_data()
# 對CSDN的論進行網頁爬取
spider = BBSpider()
spider.run()
運行結果
生成了一個data.json文件曹步,文件內容如下:
[{"content": "\u6709\u4e2a\u81ea\u8eab\u8fed\u4ee3\u51fa\u73b0\u4e86\u95ee\u9898\uff0c\u65e0\u6cd5\u7406\u89e3\u554a", "link": "https://bbs.csdn.net/topics/392468373", "time": "2018-10-27 12:10:41"}, {"content": "\u8fde\u7eed\u5c1d\u8bd56\u5c0f\u65f6\u65e0\u679c \u80fd\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u7684\u4eba\u53ef\u80fd\u4e0d\u8d85\u8fc73\u4e2a", "link": "https://bbs.csdn.net/topics/392468284", "time": "2018-10-27 02:44:34"}, {"content": "Http\u8bf7\u6c42header\u4e2d\u81ea\u5b9a\u4e49\u7684\u53c2\u6570\u662f\u5982\u4f55\u4f20\u5230PHP SERVER\u53d8\u91cf\u4e2d\u7684", "link": "https://bbs.csdn.net/topics/392468081", "time": "2018-10-26 16:39:40"}, {"content": "\u6709\u73b0\u6210winform\u57fa\u4e8e.net FX2.0\u7684\uff0c\u73b0\u5728\u7528\u8f6c\u79fb\u5230LINUX\u4e0a", "link": "https://bbs.csdn.net/topics/392468065", "time": "2018-10-26 16:25:51"}······]
以下為相關的解析:
具體代碼鏈接:https://github.com/zhuyecao/kaikeba/tree/master/kaikeba/xpath