爬虫 — Json 模块和 Post 请求

news/2024/7/19 9:23:54 标签: 爬虫, python

目录

  • 一、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()

python"># 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()

python"># 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()

python"># 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()

python"># 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 为空的可以删除,保留有值的,并且需要变成字典格式的。

python"># 需求:英汉互译

# 导入模块
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,需要用到传输的数据

在这里插入图片描述

python"># 导入模块
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

在这里插入图片描述

python"># 导入模块
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、数据拿到后,做数据解析

python"># 导入模块
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) # 打印标题和时间

注意时间转化问题,这个是固定的格式

python">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 参数不一样

python"># 导入模块
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)  # 打印标题和时间

到此,目标数据获取完成。

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


http://www.niftyadmin.cn/n/5028928.html

相关文章

【Leetcode Sheet】Weekly Practice 6

Leetcode Test 2605 从两个数字数组里生成最小数字(9.5) 给你两个只包含 1 到 9 之间数字的数组 nums1 和 nums2 &#xff0c;每个数组中的元素 互不相同 &#xff0c;请你返回 最小 的数字&#xff0c;两个数组都 至少 包含这个数字的某个数位。 提示&#xff1a; 1 < …

python pdf文件转图片

在Python中&#xff0c;有很多的第三方库可以用于PDF文件的转换&#xff0c;比如PyPDF2和pdf2image。 其中PyPDF2可以从PDF文件中提取每一页并将其保存为图像文件&#xff0c;需要安装Pillow库。 pdf2image则直接将PDF文件转换为PNG或JPEG图像文件&#xff0c;可以使用ImageM…

如何制作表情包gif图?一个方法分分钟制作

在现在网络通讯工具中gif表情包是必不可少的。很多时候&#xff0c;流行的gif表情包不太符合自己的需求&#xff0c;想要自己制作一个的时候应该怎么办呢&#xff1f;很简单通过使用gif动画制作&#xff08;https://www.gif.cn/&#xff09;工具-GIF中文网&#xff0c;无需下载…

v-model绑定导致的element UI文本框输入第一次值后被绑定,导致空文本框无法再输入文字

在工作岗位上&#xff0c;上边分配一个任务&#xff0c;创建一个页面&#xff0c;从0-1&#xff0c;全部自己搭建&#xff0c;也没有啥模版&#xff0c;就这么来&#xff0c;那就直接来吧&#xff0c;没办法&#xff0c;那就直接上手&#xff0c;开发过程中&#xff0c;我使用了…

stm32----ADC模数转换

一、ADC介绍 ADC&#xff0c;即模数转换器&#xff0c;它可以将模拟信号转化为数字信号。在stm32种一般有3个ADC&#xff0c;每个ADC有18个通道。 12位ADC是一种逐次逼近型模拟数字转换器&#xff0c;它有多达18个通道&#xff0c;可测量16个外部和两个内部信号源。各个通道的A…

应用在电子体温计中的国产温度传感芯片

电子体温计由温度传感芯片&#xff0c;液晶显示器&#xff0c;纽扣电池&#xff0c;专用集成电路及其他电子元器件组成。能快速准确地测量人体体温&#xff0c;与传统的水银玻璃体温计相比&#xff0c;具有读数方便&#xff0c;测量时间短&#xff0c;测量精度高&#xff0c;能…

UI自动化测试神器Playwright(Java版)(保存登录cookie,解决免登录)

&#x1f3ad; Playwright在称为浏览器上下文的隔离环境中执行测试。该隔离模型提高了可重复性并防止相关联的测试脚本执行失败。测试可以加载现有的已验证状态&#xff0c;比如获取已登录的状态&#xff08;Cookie&#xff09;&#xff0c;在后续脚本中复用。这消除了在每个测…

页面上下左右滑动事件

1.下载插件 npm install vue-touchnext -S 2.main.js加入以下代码 import VueTouch from vue-touch Vue.use(VueTouch, { name: v-touch }) VueTouch.config.swipe { threshold: 50 //设置左右滑动的距离 } 3.完整代码 <template><div><v-touch swipe…