天天看點

資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

文章目錄

  • 爬蟲中資料的分類
  • json的資料提取
    • json子產品中的方法
  • jsonpath子產品的學習
    • jsonpath文法
    • 小案例1拉鈎json解析
    • 小案例2 豆瓣影評案例:

爬蟲中資料的分類

在爬蟲爬取的資料中有很多不同類型的資料,我們需要了解資料的不同類型來有規律的提取和解析資料。

結構化資料:json,xml等

處理方式:直接轉化為python類型

非結構化資料:HTML

處理方式:正規表達式、xpath等

資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

其實每個方法都不難,看看使用文檔都很容易了解,我一般遇到html,xml資料使用lxml裡的xpath文法解析提取,遇到json資料用jsonpath文法提取。

json的資料提取

JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式,它使得人們很容易的進行閱讀和編寫。同時也友善了機器進行解析和生成。适用于進行資料互動的場景,比如網站前台與背景之間的資料互動。

在網站提取的json資料比較亂,如豆瓣的一條json資料:豆瓣電影影評json資料

可以放到

json.cn

,這個網站去解析,友善檢視結構,示例:

資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

json子產品中的方法

import json
#json.dumps 實作python類型轉化為json字元串
#indent實作換行和空格
#ensure_ascii=False實作讓中文寫入的時候保持為中文
json_str = json.dumps(mydict,indent=2,ensure_ascii=False)

#json.loads 實作json字元串轉化為python的資料類型
my_dict = json.loads(json_str)


#json.dump 實作把python類型寫入類檔案對象
# 具有read()或者write()方法的對象就是類檔案對象,
#比如f = open(“a.txt”,”r”) f就是類檔案對象
with open("1.txt","w") as f:
    json.dump(mydict,f,ensure_ascii=False,indent=2)

# json.load 實作類檔案對象中的json字元串轉化為python類型
with open("1.txt","r") as f:
    my_dict = json.load(f)
           

jsonpath子產品的學習

jsonpath是用來解析多層嵌套的json資料;JsonPath 是一種資訊抽取類庫,是從JSON文檔中抽取指定資訊的工具,提供多種語言實作版本,包括:Javascript, Python, PHP 和 Java。

安裝方法:pip install jsonpath

官方文檔:http://goessner.net/articles/JsonPath

jsonpath文法

資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

使用示例,如下面:

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
           
資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

小案例1拉鈎json解析

簡單示例,如擷取拉鈎網[拉鈎json資料],(https://www.lagou.com/lbs/getAllCitySearchLabels.json)所有城市名字,資料在json.cn網站上解析是這樣的

資料提取之jsonpath爬蟲中資料的分類json的資料提取jsonpath子產品的學習

是以擷取城市名字的jsonpath文法可以這樣寫

$..name

,python代碼示例:

import jsonpath
import json
import requests

url = 'https://www.lagou.com/lbs/getAllCitySearchLabels.json'
headers_ = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
        }

str_data = requests.get(url,headers = headers_).text
dict_data = json.loads(str_data)
# 第一個參數是字典對象,第二個參數是jsonpath表達式
ret = jsonpath.jsonpath(dict_data, '$..name')
print(ret)
           

小案例2 豆瓣影評案例:

import requests
import json
import jsonpath
import time


class DouBanSpider:
    # 初始化設定url,使用者代理
    def __init__(self):
        """
        1:https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&start=0&limit=20
        2:https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&start=20&limit=20
        3:https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&start=40&limit=20
        """
        # 把發生變化的參數部分 start 拿掉
        self.url_ = 'https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&&limit=20'
        # 使用者代理UA
        self.headers_ = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
        }

    # 發送請求,得到相應,提取内容
    def send_request(self, page):  # 隻發送一個請求,翻頁不再這裡做
        # url參數字典的設定
        page_params = {
            'start': int(page) * 20
        }
        # 發送get請求, 得到對象的響應對象
        response_ = requests.get(self.url_, headers=self.headers_, params=page_params)
        py_data = response_.json()  # 直接把響應對象的json str 轉換成了 python類型的資料
        return py_data  # 還沒有解析過的整個json的資料

    # 解析完儲存再本地
    def save_data(self, data_):  # 接受的json資料之後 解析儲存
        title_list = jsonpath.jsonpath(data_, '$..title')  # 取到名稱 清單
        score_list = jsonpath.jsonpath(data_, '$..score')  # 取到評分 清單

        # 儲存在本地
        for i in range(len(title_list)):
            dict_ = {}
            dict_[title_list[i]] = score_list[i]  # 是一個字典
            # 儲存成json格式
            json_data = json.dumps(dict_, ensure_ascii=False) + ',\n'  # 為了每條資料換行
            with open('douban.json', 'a', encoding='utf-8') as f:
                f.write(json_data)

    # 排程方法

    def run(self):
        pages = int(input('請輸入你想要抓取的頁數:'))
        for page in range(pages):
            # 調用發送請求的方法
            data_ = self.send_request(page)
            #    儲存
            self.save_data(data_)
            print(f'第{page+1}頁資料儲存完畢......')
            time.sleep(1)


if __name__ == '__main__':
    douban_ = DouBanSpider()
    douban_.run()