類比關係,jsonpath與json的關係,類似於XPath對於XML
Jsonpath與XPath語法對比
json結構清晰,可讀性高,複雜度低,匹配簡單。
Xpath | Jsonpath | 描述 |
---|---|---|
/ | $ | 根節點 |
. | @ | 現行節點 |
/ | . or [] | 取子節點 |
.. | n/a | 取父節點Jsonpath未支持 |
// | .. | 全局匹配,選擇所有符合的條件 |
* | * | 匹配所有元素 |
@ | n/a | 根據屬性訪問,json不支持,json是可以key-value機構 |
[] | [] | 迭代器標識 |
| | [,] | 支持迭代器多選 |
[] | ?() | 支持過濾 |
n/a | () | 支持表達式計算 |
() | n/a | 外組,jsonpath不支持 |
爬蟲爬取糗事百科的代碼實例:
import urllib2
import json
from lxml import etree
# -*- coding:utf-8 -*-
'''
獲取根節點://div[contains(@id,"qiushi_tag_")]
獲取用戶名://div[contains(@id,"qiushi_tag_")]/div/a/h2
獲取段子內容://div[contains(@id,"qiushi_tag_")]//div[@class="content"]/span
獲取點贊數和評論數://div[contains(@id,"qiushi_tag_")]//i
獲取圖片鏈接://div[contains(@id,"qiushi_tag_")]//div[@class="thumb"]//@src
'''
url = "https://www.qiushibaike.com/8hr/page/1/"
headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
requests = urllib2.Request(url,headers=headers)
html = urllib2.urlopen(requests).read()
text = etree.HTML(html)
node_list = text.xpath('//div[contains(@id,"qiushi_tag_")]')
items = {}
for node in node_list:
username = node.xpath('.div/a/@title')[0]
image = node.xpath('.//div[@calss="thumb"]//@src')
content = node.xpath('.//div[@calss="content"]/span')[0].text
zan = node.xpath('.//i')[0].text
comments = node.xpath('.//i')[1].text
items = {
"username":username,
"image":image,
"content":content,
"zan":zan,
"comments":comments,
}
with open("qiushi.json","a") as f:
f.write(json.dumps(items,ensure_ascii = False).unicode("utf-8")+"\n")
效果顯示:但是並沒有去優化代碼,使得運行效果好一些。可以使用正確的索引規則將username正確的顯示出來。
關於匹配規則其實還是很重要的,在提取信息方面,合適的匹配規則能夠節省大量的源碼分析。
閱讀更多 一兒口山石 的文章