目录
- 一、Json 模块
-
- 1、定义
- 2、方法
-
- 2.1、json.dumps()
- 2.2、json.loads()
- 2.3、json.dump()
- 2.4、json.load()
- 二、Post 请求
- 三、Post 请求携带 Json 参数案例
一、Json 模块
1、定义
Json(JavaScript Object Notation)是一种轻量级的数据交换格式,具有数据格式简单,读写方便易懂等很多优点。
许多主流的编程语言都在用它来进行前后端的数据传输,大大的简化了服务器和客户端的开发工作量。相对于 XML 来说,更加的轻量级,更方便解析,因此许多开发者都遵循 Json 格式来进行数据的传输和交换。
2、方法
方法
作用
json.dumps()
将 Python 对象转换成 Json 字符串
json.loads()
将 Json 字符串转换成 Python 对象
json.dump()
将 Python 对象转换成 Json 字符串存储到文件中
json.load()
将 Json 字符串转换成 Python 对象提取出来
2.1、json.dumps()
# json.dumps() 将 Python 对象转换成 Json 字符串
import json
s2 = {"name": "pyton"}
s3 = [{"name": "python"}]
print(type(s2), type(s3))
# <class 'dict'> <class 'list'>
# 将 python 对象转为 json 格式字符串
res1 = json.dumps(s2)
# 打印数据类型
print(type(res1)) # <class 'str'>
# 将 python 对象转为 json 格式字符串
res2 = json.dumps(s3)
# 打印数据类型
print(type(res2)) # <class 'str'>
2.2、json.loads()
# json.loads() 将 Json 字符串转换成 Python 对象
import json
import re
s1 = 'python'
s2 = '{"name": "pyton"}'
s3 = '[{"name": "python"}]'
s4 = 'jquery:[{"name": "python"}]'
print(type(s1), type(s2), type(s3), type(s4))
# <class 'str'> <class 'str'> <class 'str'> <class 'str'>
# 需求:取 python,将 str 转为 python 对象(字典,列表)
# 转换字典数据类型
res = json.loads(s2)
# 打印数据类型
print(type(res)) # <class 'dict'>
# 转换列表数据类型
res2 = json.loads(s3)
# 打印数据类型
print(type(res2)) # <class 'list'>
# 需要正则做处理
result = re.match('jquery:(.*)', s4)
# 转换列表数据类型
res3 = json.loads(result.group(1))
# 打印数据
print(res3) # [{'name': 'python'}]
print(res3[0]['name']) # python
2.3、json.dump()
# json.dump() 将 Python 对象转换成 Json 字符串存储到文件中
import json
# 字典数据类型
data = {"name": 'python', 'name1': '张三'}
# 写入文件
f = open('data.json', 'w', encoding='utf-8')
# 将字典转为 json 对象,写入 f 文件
json.dump(data, f, ensure_ascii=False)
注意:如果写入的数据包含中文-
1、文件设置编码:encoding=‘utf-8’-
2、添加参数 ensure_ascii=False,否则中文默认以 ASCII 编码写入
2.4、json.load()
# json.load() 将 Json 字符串转换成 Python 对象提取出来
import json
# 读取文件
f = open('data.json', 'r', encoding='utf-8')
# 将 json 对象转为 python 对象(字典)
j_data = json.load(f)
print(type(j_data), j_data) # <class 'dict'> {'name': 'python', 'name1':'张三'}
print(j_data['name1']) # 张三
二、Post 请求
如果遇到是 Post 请求的方式,一般来说是需要携带对应的参数。
Post 请求会多出⼀个 Payload 选项,或者直接在 Headers 这个最下面,有个 Form Data 选项,这里就会有 Post 请求需要携带的参数,把这个参数复制下来,参数当中 value 为空的可以删除,保留有值的,并且需要变成字典格式的。
# 需求:英汉互译
# 导入模块
import requests
# 确定url
url = 'https://fanyi.so.com/index/search?eng=1&validate=&ignore_trans=0&query=hello'
# 请求头
head = {
# 'accept': 'application/json, text/plain, */*',
# 'accept-encoding': 'gzip, deflate, br',
# 'accept-language': 'en,zh-CN;q=0.9,zh;q=0.8',
# 'content-length': '0',
# 'cookie': 'QiHooGUID=B3609995F987B9519A18C16A029A2638.1683789631633; Q_UDID=1ac23bf8-4082-915a-835f-5d6036ac73af; __guid=144965027.842894035891445900.1683789631247.0437; count=3',
# 'origin': 'https://fanyi.so.com',
'pro': 'fanyi',
# 'referer': 'https://fanyi.so.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-origin',
'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',
}
# post 发请求携带的参数,用 data 参数传递
eng = int(input('英译汉请输入1\n汉译英请输入0\n'))
trans = input('请输入翻译的单词')
data = {
'eng': eng, # 决定了是英译汉还是汉译英
'ignore_trans': '0',
'query': trans # 写的什么,翻译的就是什么
}
# 发送请求
res = requests.post(url, data=data,headers=head)
# 获取数据
data = res.json()
print(data['data']['fanyi'])
请求头
如果不知道网站使用了哪个反爬参数,可以全部复制过来,再做测试-
快速转换成字典数据,Ctrl + R 后选正则表达式,用’$1’: ‘$2’,替换(.?): (.)
三、Post 请求携带 Json 参数案例
目标网址:http://www.whggzy.com/-
需求:获取政策法规栏目页面面下所有文章的标题和时间
分析:
1、分析数据是动态加载还是静态加载,确定是动态加载找到当前数据包
2、找到目标网址和传输方式
3、传输方式为 POST,需要用到传输的数据
# 导入模块
import requests
# 确定 url —— 动态加载
url = 'http://www.whggzy.com/front/search/category'
# POST 请求传输数据,要携带参数
data = {"utm":"sites_group_front.2ef5001f.0.0.ca79aa90f0c811edbc17f5eb8caaceab","categoryCode":"GovernmentProcurement","pageSize":15,"pageNo":1}
# 发请求,获取响应
res = requests.post(url, data=data)
# 打印数据响应内容
print(res.text)
4、查看 Content-Type 属性,如果是 text,数据赋值的是 data=data,如果是 application/json,数据赋值的应是 json=data
# 导入模块
import requests
# 确定 url —— 动态加载
url = 'http://www.whggzy.com/front/search/category'
# POST 请求传输数据,要携带参数
data = {"utm":"sites_group_front.2ef5001f.0.0.ca79aa90f0c811edbc17f5eb8caaceab","categoryCode":"GovernmentProcurement","pageSize":15,"pageNo":1}
# 发请求,获取响应
res = requests.post(url, json=data)
# 打印数据响应内容
print(res.text)
5、数据拿到后,做数据解析
# 导入模块
import requests
import time # 时间戳内置模块
# 确定 url —— 动态加载
url = 'http://www.whggzy.com/front/search/category'
# POST 请求传输数据,要携带参数
data = {"utm":"sites_group_front.2ef5001f.0.0.ca79aa90f0c811edbc17f5eb8caaceab","categoryCode":"GovernmentProcurement","pageSize":15,"pageNo":1}
# 发请求,获取响应
res = requests.post(url, json=data)
# 打印数据响应内容
# print(res.text)
# 数据解析
result = res.json()['hits']['hits']
# print(requests)
# 遍历获取每一条数据
for j in result:
# print(j)
source = j['_source'] # 获取包含标题和时间的数据
title = source['title'] # 获取标题
publishDate = source['publishDate'] # 获取时间,获取到的时间为13位时间戳
times = time.localtime(publishDate / 1000) # 13位时间戳转时间
date = time.strftime("%Y-%m-%d %H:%M:%S", times) # 设置时间的格式
print(title, date) # 打印标题和时间
注意时间转化问题,这个是固定的格式
import time # 内置模块
# 13位时间戳转时间
tre_timeArray = time.localtime(1646012206685/1000)
# 设置时间的格式
tre_otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", tre_timeArray)
print('tre_otherStyleTime',tre_otherStyleTime)
# 10位时间戳转时间
ten_timeArray = time.localtime(1632651709)
# 设置时间的格式
ten_otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", ten_timeArray)
print('ten_otherStyleTime',ten_otherStyleTime)
# 本地时间
local_timeArray = time.localtime()
# 设置时间的格式
local_otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", local_timeArray)
print('local_otherStyleTime',local_otherStyleTime)
6、第一页数据拿到后,抓第二页数据的包
翻页数据有两种情况
1)url 会发生变化
第三页:https://movie.douban.com/top250?start=50&filter=-
第二页:https://movie.douban.com/top250?start=25&filter=-
第一页:ttps://movie.douban.com/top250?start=0&filter=-
相差 25-
构造 url-
for page in range(1, 5):-
第一页:page=1 start=0-
f’https://movie.douban.com/top250?start={(page-1)*25}&filter=’-
第二页:page=2 start=25-
f’https://movie.douban.com/top250?start={(page-1)*25}&filter=’
2)url 不会发生变化,看携带的 data 有无变化
对比第一页数据包和第二页数据包,url 相同
对比传输数据,发现 pageNo 参数不一样
# 导入模块
import requests
import time # 时间戳内置模块
# 确定 url —— 动态加载
url = 'http://www.whggzy.com/front/search/category'
# 翻页获取数据
for i in range(1, 5): # 左闭右开 1, 2, 3, 4
# POST 请求传输数据,要携带参数
data = {
"utm":"sites_group_front.2ef5001f.0.0.ca79aa90f0c811edbc17f5eb8caaceab",
"categoryCode":"GovernmentProcurement",
"pageSize":15,
"pageNo":i # 当前页码
}
# 发请求,获取响应
res = requests.post(url, json=data)
# 打印数据响应内容
# print(res.text)
# 数据解析
result = res.json()['hits']['hits']
# print(requests)
# 遍历获取每一条数据
for j in result:
# print(j)
source = j['_source'] # 获取包含标题和时间的数据
title = source['title'] # 获取标题
publishDate = source['publishDate'] # 获取时间,获取到的时间为13位时间戳
times = time.localtime(publishDate / 1000) # 13位时间戳转时间
date = time.strftime("%Y-%m-%d %H:%M:%S", times) # 设置时间的格式
print(title, date) # 打印标题和时间
到此,目标数据获取完成。
📝结尾
看到这里了还不给博主扣个:- ⛳️ 点赞☀️收藏 ⭐️ 关注!- 💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖- 拜托拜托这个真的很重要!- 你们的点赞就是博主更新最大的动力!- 有问题可以评论或者私信呢秒回哦。