爬虫 — JsonPath 和 CSV 文件读写

目录

  • 一、JsonPath
  • [二、CSV 文件读写](#二、CSV 文件读写)
    • 1、概念
    • [2、写入 CSV 文件](#2、写入 CSV 文件)
      • [2.1 方式一](#2.1 方式一)
      • [2.2 方式二](#2.2 方式二)
    • [3、读取 CSV 文件](#3、读取 CSV 文件)
      • [3.1 方式一](#3.1 方式一)
      • [3.2 方式二](#3.2 方式二)
  • [三、JsonPath + CSV 文件读写案例](#三、JsonPath + CSV 文件读写案例)

一、JsonPath

1、概念

JsonPath 是一种简单的方法来提取给定 JSON 文档的部分内容,JsonPath 有许多编程语言,如 Javascript,Python,PHP 和 JAVA。

JsonPath 提供的 JSON 解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的 JSON 内容。但 JsonPath 解析的数据只针对 JSON 格式的数据。

2、安装

JsonPath 是第三方库,需要安装

在终端运行:pip install jsonpath

3、用法

JsonPath 操作符

符号 说明
$ 查询的根节点对象,用于表示一个 JSON 数据,可以是数组或对象
@ 过滤器断言(filter predicate)处理的当前节点对象,类似 JAVA 中的 this 字段
* 通配符,可以表示一个名字或数字
. . 可以理解为递归搜索
. 表示一个子节点
'name'(,'') 表示一个或多个子节点
(,) 表示一个或多个数组下标
start:end 数组片段,区间为[start, end), 不包含end
?() 过滤器表达式,表达式结果必须是boolean
python 复制代码
# 数据
dic = {
    "resultCode": "1",
    "resultMsg": "success",
    "reqId": "52f9f3e1-1d76-47b4-b2ae-226633b61476",
    "systemTime": "1681991278593",
    "videoInfo": {  # 父亲
        "playSta": "1",
        "video_image": "https://image.pearvideo.com/cont/20170714/cont-1110173-10436784.png",
        "srcUrl": "https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-aaa.mp4",
        "videos": {  # 儿子
            "hdUrl": "",
            "hdflvUrl": "",
            "sdUrl": "",
            "sdflvUrl": "",  # 孙子
            "srcUrl": "https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4"
        }
    }
}

3.1、. .

递归搜索,不需要考虑节点位置获取数据。

jsonpath.jsonpath(数据, '$. .key')

python 复制代码
print(jsonpath.jsonpath(dic, '$..srcUrl'))
# 返回值
# ['https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-aaa.mp4', 'https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4']

print(jsonpath.jsonpath(dic, '$..video_image'))
# 返回值
# ['https://image.pearvideo.com/cont/20170714/cont-1110173-10436784.png']

print(jsonpath.jsonpath(dic, '$..[playSta,video_image]'))
# 返回值
# ['1', 'https://image.pearvideo.com/cont/20170714/cont-1110173-10436784.png']

3.2、.

匹配下一级的标签(子集)。

python 复制代码
print(jsonpath.jsonpath(dic, '$..srcUrl')[0])
# 返回值
# https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-aaa.mp4

print(jsonpath.jsonpath(dic, '$..videoInfo.srcUrl'))
# 返回值
# ['https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-aaa.mp4']

print(jsonpath.jsonpath(dic, '$..videos.srcUrl'))
# 返回值
# ['https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4']
python 复制代码
# 数据
dic = {
    "resultCode": "1",
    "resultMsg": "success",
    "reqId": "52f9f3e1-1d76-47b4-b2ae-226633b61476",
    "systemTime": "1681991278593",
    "videoInfo": {
        "playSta": "1",
        "video_image": "https://image.pearvideo.com/cont/20170714/cont-1110173-10436784.png",
        "videos": [
            {
                "hdUrl": "1",
                "hdflvUrl": "",
                "sdUrl": "",
                "sdflvUrl": "bbbbbb",
            },
            {
                "hdUrl": "",
                "hdflvUrl": "",
                "sdUrl": "",
                "sdflvUrl": "cccccc",
                "srcUrl": "https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4"
            },
            {
                "hdUrl": "",
                "hdflvUrl": "",
                "sdUrl": "",
                "sdflvUrl": "dddddd",
                "srcUrl": "https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4"
            },
        ]
    }
}

3.3、@

正在处理的当前节点,?:过滤器。

python 复制代码
# 只取 videos 列表里,包含 srcUrl 的对象
print(jsonpath.jsonpath(dic, '$..videos[?(@.srcUrl)]'))
# 返回值
# [{'hdUrl': '', 'hdflvUrl': '', 'sdUrl': '', 'sdflvUrl': 'cccccc', 'srcUrl': 'https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4'}, {'hdUrl': '', 'hdflvUrl': '', 'sdUrl': '', 'sdflvUrl': 'dddddd', 'srcUrl': 'https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4'}]

# 获取所有 key 为 srcUrl 的值
print(jsonpath.jsonpath(dic, '$..srcUrl'))
# 返回值
# ['https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4', 'https://video.pearvideo.com/mp4/short/20170714/1681991278593-10632788-hd.mp4']

# 根据值筛选数据
print(jsonpath.jsonpath(dic, '$..videos[?(@.hdUrl=="1")]'))
# 返回值
# [{'hdUrl': '1', 'hdflvUrl': '', 'sdUrl': '', 'sdflvUrl': 'bbbbbb'}]

3.4、*

通配符,可以表示一个名字或数字。

python 复制代码
# 多个子节点,通过下标,获取第一个对象 sdflvUrl 值
print(jsonpath.jsonpath(dic, '$..videos[0].sdflvUrl'))
# 返回值
# ['bbbbbb']

# 多个子节点,通过下标,获取第一和第二两个对象 sdflvUrl 值
print(jsonpath.jsonpath(dic, '$..videos[0,1].sdflvUrl'))
# 返回值
# ['bbbbbb', 'cccccc']

# 取所有节点
print(jsonpath.jsonpath(dic, '$..videos[*].sdflvUrl'))
# 返回值
# ['bbbbbb', 'cccccc', 'dddddd']

3.5、start:end

数组片段,区间为[start, end),不包含end。

python 复制代码
# 列表下标,取两个数据 ------ 切片,取1,2
print(jsonpath.jsonpath(dic, '$..videos[1:3].sdflvUrl'))
# 返回值
# ['cccccc', 'dddddd']

二、CSV 文件读写

1、概念

CSV (Comma Separated Values),是一种常用的文本格式,用以存储表格数据,包括数字或者字符。很多程序在处理数据时都会碰到 CSV 这种格式的文件。

Python 自带了 CSV 模块,专门用于处理 CSV 文件的读取。

2、写入 CSV 文件

2.1 方式一

python 复制代码
# 导入模块
import csv

# 爬取下来的数据
data = [('肖申克的救赎', '9.7', '希望让人自由'), ('霸王别姬', '9.6', '风华绝代'), ('阿甘正传', '9.5', '一部美国近现代史')]

# 设置表头
head = ('电影名', '评分', '简介')

# 保存
# 'w':写入,encoding='utf-8-sig':编码格式,newline='':清除空行
with open('douban.csv','w',encoding='utf-8-sig',newline='') as f:
    # 创建 csv 写入对象
    writer = csv.writer(f)
    # 写入表头
    writer.writerow(head)
    # 写入数据
    writer.writerows(data)

2.2 方式二

python 复制代码
# 导入模块
import csv

# 列表嵌套字典格式数据
data = [
    {'标题': '肖申克的救赎', '评分': '9.7', '引言': '希望让人自由'},
    {'标题': '霸王别姬', '评分': '9.6', '引言': '风华绝代'},
    {'标题': '阿甘正传', '评分': '9.5', '引言': '一部美国近现代史'}
]

# 设置表头,key 必须要跟表头保持一致
head = ('标题', '评分', '引言')

# 创建文件对象
with open('douban1.csv', 'w', encoding='utf-8-sig', newline='') as f:
    # 创建 csv 字典写入对象,fieldnames 固定参数,不可修改
    writer = csv.DictWriter(f, fieldnames=head)  # 设置表头
    # 写入表头
    writer.writeheader()
    # 写入数据
    writer.writerows(data)
'''
如果出现报错信息
ValueError: dict contains fields not in fieldnames: '标题', '引言'
检查表头是否与字典当中的 key 保持一致
'''

3、读取 CSV 文件

3.1 方式一

python 复制代码
# 导入模块
import csv

# 读取数据
with open('douban.csv','r', encoding='utf-8-sig') as f:
    # 创建 csv 读取对象
    read = csv.reader(f)
    # 不读取表头
    next(read)
    # list列表,直接下标取值
    for i in read:
        print(i)

3.2 方式二

python 复制代码
# 导入模块
import csv

# 读取数据
with open('douban.csv','r', encoding='utf-8-sig') as f:
    # 创建 csv 读取对象,返回数据为字典格式
    read = csv.DictReader(f)
    # dict 字典,通过 key 取值
    for i in read:
        print(i['电影名'])

w:写入数据(重新写入,覆盖)

r:读取数据

a:追加,文件原有的内容基础上添加新的内容

wb:保存视频,图片,音频

三、JsonPath + CSV 文件读写案例

目标网站:'https://www.liepin.com/zhaopin/?inputFrom=www_index\&workYearCode=0\&key=python\&scene=input\&ckId=wodpawgkbhefdidqtq1hso4xqml8alw9\&dq='

翻页爬取前两页的数据(职位名称,公司地点,薪资)

python 复制代码
# 导入模块
import requests
import csv

# 指定url
url = 'https://api-c.liepin.com/api/com.liepin.searchfront4c.pc-search-job'

# 设置请求头参数
head = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8',
    'Connection': 'keep-alive',
    'Content-Length': '406',
    'Content-Type': 'application/json;charset=UTF-8;',
    'Cookie': 'XSRF-TOKEN=Bh2gi6GcTtqIvM4lrU3m4g; __gc_id=f204bf9d8cc34c659470e09660711986; _ga=GA1.1.1267984231.1683208911; __uuid=1683208911082.70; __tlog=1683208911084.44%7C00000000%7C00000000%7C00000000%7C00000000; Hm_lvt_a2647413544f5a04f00da7eee0d5e200=1683208911; __session_seq=13; __uv_seq=13; Hm_lpvt_a2647413544f5a04f00da7eee0d5e200=1683210035; _ga_54YTJKWN86=GS1.1.1683208911.1.1.1683211483.0.0.0',
    'Host': 'api-c.liepin.com',
    'Origin': 'https://www.liepin.com',
    'Referer': 'https://www.liepin.com/',
    'sec-ch-ua': '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
    'X-Client-Type': 'web',
    'X-Fscp-Bi-Stat': '{"location": "https://www.liepin.com/zhaopin/?inputFrom=www_index&workYearCode=0&key=python&scene=input&ckId=wodpawgkbhefdidqtq1hso4xqml8alw9&dq="}',
    'X-Fscp-Fe-Version': '',
    'X-Fscp-Std-Info': '{"client_id": "40108"}',
    'X-Fscp-Trace-Id': '046a4cc3-72bc-4b95-8f7a-c39df3ee11d8',
    'X-Fscp-Version': '1.1',
    'X-Requested-With': 'XMLHttpRequest',
    'X-XSRF-TOKEN': 'Bh2gi6GcTtqIvM4lrU3m4g',
}

# 表格数据
csvList = []

# 获取前两页数据
for i in range(0, 2):

    # post请求参数
    data = {"data":{"mainSearchPcConditionForm":{"city":"410","dq":"410","pubTime":"","currentPage":i,"pageSize":40,"key":"python","suggestTag":"","workYearCode":"0","compId":"","compName":"","compTag":"","industry":"","salary":"","jobKind":"","compScale":"","compKind":"","compStage":"","eduLevel":""},"passThroughForm":{"scene":"input","skId":"","fkId":"","ckId":"vmglvn6pyc3nv5scebhp02euhaexpkd8"}}}

    # 发送请求
    res = requests.post(url, headers=head, json=data)

    # 获取响应内容
    json_data = res.json() # 获取json格式的数据
    result = json_data['data']['data']['jobCardList']
    # print(result)

    # 循环获取所需数据
    for j in result:
        # 职位名称
        title = j['job']['title']
        # 薪资
        salary = j['job']['salary']
        # 公司地点
        compName = j['comp']['compName']
        # 打印所需数据
        print(title, salary, compName)

        # 追加表格数据
        csvList.append((title, salary, compName))
# print(csvList)

# 规定表头
tableHead = ('职位名称','薪资','公司地点')

# 创建文件对象
with open('liepin.csv', 'w', encoding='utf-8-sig', newline='') as f:
    # 创建csv写入对象
    writer = csv.writer(f)
    # 写入表头
    writer.writerow(tableHead)
    # 写入数据
    writer.writerows(csvList)

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

相关推荐
Angel Q.6 小时前
特征提取 | DINO 到 DINOv3
图像处理·python
不如语冰7 小时前
AI大模型入门-pytorch-张量2 tensor创建
python
NPE~7 小时前
[AI]Agent开发——ADK框架使用
人工智能·python·ai·教程·adk·agent开发
矮个史蒂芬7 小时前
统计verilog .v文件中output 的bit数
python
gwf2167 小时前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
爱吃提升8 小时前
python 分布式爬虫、爬虫合规与综合实战项目
分布式·爬虫·python
审小匠OpenCPAi8 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
元Y亨H9 小时前
Pandas 解析 Excel 导致的内存溢出(MemoryError)
python·excel
金銀銅鐵10 小时前
[Python] 用 turtle 来绘制瑞典国旗
python
Albert Edison10 小时前
【GUI 自动化测试】Pywinauto 常见操作
自动化测试·python·pywinauto