Python爬蟲json和JsonPath系列之十一

1,json中四個重要的方法

  • Json結構清晰,可讀性高,複雜度低,非常容易匹配。

1. json.loads()

把Json格式字符串解碼轉換成Python對象

從json到python的類型轉化對照如下:

這裏寫圖片描述

2. json.dumps()

實現python類型轉化爲json字符串,返回一個str對象 。

從python原始類型向json類型的轉化對照如下:

這裏寫圖片描述

3. json.dump()

將Python內置類型序列化爲json對象後寫入文件

4. json.load()

讀取文件中json形式的字符串元素 轉化成python類型

5,注意事項:

json.loads() 是把 Json格式字符串解碼轉換成Python對象,如果在json.loads的時候出錯,要注意被解碼的Json字符的編碼,如果傳入的字符串的編碼不是UTF-8的話,需要指定字符編碼的參數encoding

如:

dataDict = json.loads(jsonStrGBK);

jsonStrGBK是JSON字符串,假設其編碼本身是非UTF-8的話而是GBK 的,那麼上述代碼會導致出錯,改爲對應的:

 dataDict = json.loads(jsonStrGBK, encoding="GBK");
  • 任何平臺的任何編碼 都能和 Unicode 互相轉換
  • decode的作用是將其他編碼的字符串轉換成 Unicode 編碼
  • encode的作用是將 Unicode 編碼轉換成其他編碼的字符串
  • 一句話:UTF-8是對Unicode字符集進行編碼的一種編碼方式

2,JsonPath

JsonPath 是一種信息抽取類庫,是從JSON文檔中抽取指定信息的工具。

  • JsonPath與XPath語法對比:

這裏寫圖片描述

3,爬取某招聘網站職位信息案例

import requests
import json
import jsonpath


class LagouSpider:
    def __init__(self):
        self.headers = {
            # 模擬真實的瀏覽器,把請求頭全部都加上
            # "Accept" : "application/json, text/javascript, */*; q=0.01",
            # "Accept-Encoding" : "gzip, deflate, br",
            # "Accept-Language" : "zh-CN,zh;q=0.8",
            # "Connection" : "keep-alive",
            # "Content-Length" : "43",
            # "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
            "Cookie": "user_trace_token=20170626172300-2aa5eb9c81db4093b6491f60c504f9a1; LGUID=20170626172300-0c74fdbf-5a51-11e7-89d3-525400f775ce; index_location_city=%E5%8C%97%E4%BA%AC; JSESSIONID=ABAAABAACDBABJB0A65566C403D46573532367CBEEF2AB5; PRE_UTM=; PRE_HOST=; PRE_SITE=; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; _gid=GA1.2.327690172.1500516674; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1498468981,1500406505,1500516674; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1500518676; _ga=GA1.2.764300251.1498468981; LGSID=20170720104259-2462b23d-6cf5-11e7-ae7e-525400f775ce; LGRID=20170720104435-5db33ef4-6cf5-11e7-ae8d-525400f775ce; TG-TRACK-CODE=search_code; SEARCH_ID=36027e19a74f4ceaab54f35baae12a30",
            "Host": "www.lagou.com",
            "Origin": "https://www.lagou.com",

            # 反爬第二步,標記瀏覽器的來源,從查看網頁源碼可知
            "Referer": "https://www.lagou.com/jobs/list_python%E7%88%AC%E8%99%AB?labelWords=&fromSearch=true&suginput=",
            # 反爬第一步
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
            "X-Anit-Forge-Code": "0",
            "X-Anit-Forge-Token": "None",
            "X-Requested-With": "XMLHttpRequest"
        }

        # url地址固定部分
        self.baseURL = "https://www.lagou.com/jobs/positionAjax.json?"
        self.positionName = input("請輸入需要查詢的職位名:")
        self.cityName = input("請輸入需要查詢的城市名:")
        self.endPage = int(input("請輸入需要爬取的頁數:"))
        # post的頁碼數據
        self.page = 1
        # 添加代理
        # self.proxy = {"http" : "123.23.232.11:8080"}

    def startWrok(self):
        # 存儲loadPage()返回的所有職位信息
        item_list = []
        while self.page <= self.endPage:
            # 獲取每一頁的職位信息列表
            position_list = self.loadPage()
            # 合併所有頁的職位信息
            item_list += position_list
            # 每獲取一頁,頁碼自增1
            self.page += 1
        # 禁用ascii處理中文,返回json格式的字符串,返回Unicode
        content = json.dumps(item_list, ensure_ascii=False)
        # 將數據寫入到磁盤文件裏
        with open("lagou_info.json", "w") as f:
            f.write(content)

    def loadPage(self):
        # url的查詢字符串,post請求採參數
        params = {"city": self.cityName, "needAddtionalResult": "false"}
        # post的表單數據
        formdata = {"first": "true", "pn": self.page, "kd": self.positionName}
        try:
            print("[LOG]: 正在抓取 %d 頁..." % self.page)
            response_result = requests.post(self.baseURL, params=params, data=formdata, headers=self.headers)
            # 代理使用: proxies = self.proxy)
        except Exception as e:
            print("[LOG]: 抓取失敗...")
            print(e)
        # time.sleep(2)
        # html = response.content
        # jsonobj = json.loads(html)

        # 按json格式獲取requests響應,Python數據類型
        jsonobj = response_result.json()

        """
        # urllib2 的用法
        params = urllib.urlencode(params)
        data = urllib.urlencode(formdata)
        url = self.baseURL + params
        request = urllib2.Request(url, data = data, headers = self.headers)
        response = urllib2.urlopen(request)
        jsonobj = json.loads(response.read())
        """

        try:
            # 通過jsonpath獲取json裏的result部分
            result_list = jsonpath.jsonpath(jsonobj, "$..result")[0]
            # 存儲當前頁的職位信息
            position_list = []
            # 處理每一條職位信息
            for result in result_list:
                # 獲取每條職位信息的部分數據
                item = {}
                item['城市'] = result['city'] if result['city'] else "NULL"
                item['公司名'] = result['companyFullName'] if result['companyFullName'] else "NULL"
                item['發佈時間'] = result['createTime'] if result['createTime'] else "NULL"
                item['區域'] = result['district'] if result['district'] else "NULL"
                item['職位'] = result['positionName'] if result['positionName'] else "NULL"
                item['薪水'] = result['salary'] if result['salary'] else "NULL"

                position_list.append(item)
            return position_list

        except Exception as  e:
            print("[ERR]: 獲取數據失敗...")
            print(e)
            return []


if __name__ == "__main__":
    spider = LagouSpider()
    spider.startWrok()

4,把json格式的文件轉爲csv格式的文件

# 處理json文本
import json
# 處理csv
import csv

# 創建csv文件對象
csvFile = open("lagou_info.csv", "w")
# 創建csv文件的讀寫對象,可以用來對csv進行讀寫操作
csv_writer = csv.writer(csvFile)

# 創建json文件對象
jsonFile = open("lagou_info.json", "r")
# 讀取本地磁盤json文件,返回原本的數據類型:列表
content_list = json.load(jsonFile)

# 獲取表頭部分
sheet = content_list[0].keys()

# 將所有的數據放到一個大列表裏
data = [content.values() for content in content_list]

# writerow 表示寫入一行數據,參數是一個列表
csv_writer.writerow(sheet)
# writerows 表示寫入多行數據,參數是一個列表(包含所有數據)
csv_writer.writerows(data)

csvFile.close()
jsonFile.close()
發佈了176 篇原創文章 · 獲贊 224 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章