python~http的请求参数中携带map

背景

调试 http GET请求的 map 参数,链路携带参数一直有问题,最终采用如下方式携带map 解决

user={"demo":"true","info":"王者"}

url encode之后的效果如下所示

user=%7B%22demo%22:%22true%22,%22info%22:%22%E7%8E%8B%E8%80%85%22%7D

最终http的url如下:

http://www.demo.com?user=%7B%22demo%22:%22true%22,%22info%22:%22%E7%8E%8B%E8%80%85%22%7D

代码

方式一

tmp = {"demo":"true","info":"王者"}
json_str = json.dumps(tmp)
encoded_str = urllib.parse.quote(json_str)
url += '&user=%s' % encoded_str

方式二

tmp = {"demo":"true","info":"王者"}
params['user'] = json.dumps(tmp)
r = requests.get(url, headers=headers, params=params, timeout=2)

urllib.parse.quote

URL 中,某些字符具有特殊含义
例如 / 用于分隔 URL 的不同部分,? 用于标识查询字符串的起始,& 用于分隔查询字符串中的不同参数等

当需要在 URL 里包含可能与这些特殊字符冲突的字符(像空格、中文、?&=等特殊符号等)时,就必须对这些字符进行 url 编码,以保证 URL 的正确性和完整性
urllib.parse.quote 函数的作用就是把字符串里的特殊字符转换为符合 URL 规范的编码形式

urllib.parse.quote 函数采用的是百分号编码(Percent-encoding)规则,也称作 URL 编码。在此编码规则下,每个特殊字符会被替换成 % 后面跟着两个十六进制数字,这两个数字代表该字符的 ASCII 码值。比如,空格会被编码为 %20,中文等非 ASCII 字符会先转化为 UTF-8 字节序列,然后每个字节再进行百分号编码

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

string:
这是必需参数,指的是需要进行 URL 编码的字符串

safe:
可选,指定哪些字符不需要进行编码,默认值为 /,意味着 / 字符不会被编码
可以根据实际需求修改这个参数,例如 safe=‘’ 表示对所有字符都进行编码

encoding:
可选,指定字符串的编码方式,默认使用 UTF - 8 编码

errors:
可选,指定编码错误的处理方式,默认值为 ‘strict’,表示遇到编码错误时会抛出异常

示例

import urllib.parse

# 包含特殊字符和中文的字符串
string_to_encode = "你好, world! & / ? ="

# 进行 URL 编码
encoded_string = urllib.parse.quote(string_to_encode)

print(encoded_string)

效果

%E4%BD%A0%E5%A5%BD%2C%20world%21%20%26%20/%20%3F%20%3D

编码学习

百分号编码(Percent-encoding)也称为 URL 编码,它将非 ASCII 字符先转换为 UTF-8 字节序列,然后每个字节再用 % 加上对应的两位十六进制数来表示。

如何将汉字 “我” 转换为 %E6%88%91
字符编码为 UTF-8 字节序列:在 UTF-8 编码中,不同的字符会被编码为不同长度的字节序列。像汉字通常会被编码为 3 个字节。“我” 这个字在 UTF-8 编码下对应的字节序列是 0xE6 0x88 0x91
转换为百分号编码形式:把每个字节转换为 % 加上对应的两位十六进制数。
例如,字节 0xE6 转换为 %E6,字节 0x88 转换为 %88,字节 0x91 转换为 %91。最终 “我” 就被编码为 %E6%88%91

cat demo.py 
# coding: utf-8

# 定义要编码的字符
char = "我"

# 对字符进行 UTF-8 编码,得到字节序列
utf8_bytes = char.encode('utf-8')

# 将字节序列转换为百分号编码形式
percent_encoded = ''.join(f'%{byte:02X}' for byte in utf8_bytes)

# %E6%88%91
print(percent_encoded)

url编码时,为什么有些编码是把空格编码为+,有些则编码为%20

主要取决于使用的编码规范和具体场景

历史背景与规范差异

+ 编码(application/x-www-form-urlencoded)

表单提交规范:在 HTML 表单使用 POST 方法提交数据时,如果表单的 enctype 属性设置为 application/x-www-form-urlencoded(这是表单提交的默认编码类型),空格会被编码为 +。这个规范源自早期的互联网实践,是为了在传输数据时能够更紧凑地表示空格,因为 +%20 占用的字符更少

相关标准:这种编码方式在 HTML 表单数据处理和一些老的 CGI(Common Gateway Interface)程序中广泛使用。例如,当在一个 HTML 表单中输入包含空格的内容并提交时,服务器端接收到的数据里空格就会以 + 的形式呈现。

%20 编码(通用 URL 编码)

RFC 3986 标准:根据互联网工程任务组(IETF)发布的 RFC 3986 标准,在通用的 URL 编码中,空格应该被编码为 %20。这个标准定义了统一的 URI(Uniform Resource Identifier)语法和编码规则,适用于各种类型的 URL,包括路径、查询参数等。
通用性和兼容性:%20 编码更具通用性和兼容性,因为它遵循了标准的百分号编码规则,可以确保在不同的系统和应用程序中正确解析。在大多数现代的 HTTP 请求库和工具中,默认使用 %20 来编码空格。

不同编程语言和库的处理方式

使用 + 编码的情况

Python 的 urllib.urlencode(Python 2):
在 Python 2 的 urllib 模块中,urlencode 函数默认将空格编码为 +,这是为了与 application/x-www-form-urlencoded 规范保持一致

# coding: utf-8

import urllib

params = {'key': 'hello world'}
encoded_params = urllib.urlencode(params)

# 输出: key=hello+world
print encoded_params

使用 %20 编码的情况

Python 的 urllib.parse.quote(Python 3):
在 Python 3 的 urllib.parse 模块中,quote 函数遵循 RFC 3986 标准,将空格编码为 %20

# coding: utf-8

import urllib.parse

string = 'hello world'
encoded_string = urllib.parse.quote(string)

# 输出: hello%20world
print(encoded_string)

requests处理时的 params 默认做法

# coding: utf-8

import requests

params = {'key': 'hello world'}
resp = requests.get('http://example.com', params=params)

# http://example.com/?key=hello+world
print(resp.url)
# <Response [200]>
print(resp)

示例

# coding: utf-8

import json
import requests

user= {
    "demo": "true",
    "info": "王者"
}
# {'user': '{"demo": "true", "info": "\\u738b\\u8005"}'} map以这种方式json化有空格
user_str = json.dumps(user)
params = {'user': user_str}
response = requests.get('http://example.com', params=params)

# http://example.com/?user=%7B%22demo%22%3A+%22true%22%2C+%22info%22%3A+%22%5Cu738b%5Cu8005%22%7D
print(response.url)
# <Response [200]>
print(response)

手动挨个编码

# coding: utf-8

import requests
import urllib.parse

# 定义参数
original_params = {
    'key': 'hello world'
}

# 手动编码参数值
encoded_params = {key: urllib.parse.quote(value) for key, value in original_params.items()}

url = 'http://httpbin.org/get'
response = requests.get(url, params=encoded_params)

# http://httpbin.org/get?key=hello%2520world
print(response.url)

编码过度了,编码了两遍

使用%20

# coding: utf-8
import requests
import urllib.parse

# 定义参数
original_params = {
    'key': 'hello world'
}

# 手动编码参数值并构建参数字符串
param_list = []
for key, value in original_params.items():
    encoded_value = urllib.parse.quote(value)
    param_list.append(f"{key}={encoded_value}")
param_string = '&'.join(param_list)

base_url = 'http://httpbin.org/get'
full_url = f"{base_url}?{param_string}"

# http://httpbin.org/get?key=hello%20world
response = requests.get(full_url)
print(response.url)

总结

空格编码为 + 主要用于 HTML 表单提交和一些遵循 application/x-www-form-urlencoded 规范的场景
空格编码为 %20 遵循 RFC 3986 标准,适用于通用的 URL 编码,具有更好的通用性和兼容性

在实际应用中,需要根据具体的需求和场景选择合适的编码方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/977293.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Crack SmartGit

感谢大佬提供的资源 一、正常安装SmartGit 二、下载crackSmartGit crackSmartGit 发行版 - Gitee.com 三、使用crackSmartGit 1. 打开用户目录&#xff1a;C:\Users%用户名%\AppData\Roaming\syntevo\SmartGit。将crackSmartGit.jar和license.zip拷贝至 用户目录。 2. 用户…

性能巅峰对决:Rust vs C++ —— 速度、安全与权衡的艺术

??关注&#xff0c;带你探索Java的奥秘&#xff01;?? ??超萌技术攻略&#xff0c;轻松晋级编程高手&#xff01;?? ??技术宝库已备好&#xff0c;就等你来挖掘&#xff01;?? ??订阅&#xff0c;智趣学习不孤单&#xff01;?? ??即刻启航&#xff0c;编…

面试题 - Vue 3 如何优化性能?

面试题 - Vue 3 如何优化性能&#xff1f; 最近&#xff0c;总有小伙伴来问我&#xff0c;在面试时应该如何回答关于优化方面的问题。其实&#xff0c;我们在日常的项目开发中&#xff0c;或多或少都接触过一些优化技巧&#xff0c;只是有时候自己没有特别留意&#xff0c;或者…

easyexcel和poi同时存在版本问题,使用easyexcel导出excel设置日期格式

这两天在使用easyexcel导出excel的时候日期格式全都是字符串导致导出的excel列无法筛选 后来调整了一下终于弄好了&#xff0c;看一下最终效果 这里涉及到easyexcel和poi版本冲突的问题&#xff0c;一直没搞定&#xff0c;最后狠下心来把所有的都升级到了最新版&#xff0c;然…

MTK-Android13-包安装器PackageInstaller 静默安装实现

目的 我们最终是为了搞明白安装的整个流程。一方面通过安卓系统自带的包安装器来了解PMS 安装流程&#xff1b;另一方面熟悉框架层Framework 针对Android apk 安装流程。 前两篇文章分析了PackagerInstaller 安装流程。 Android13-包安装器PackageInstaller-之apk安装跳转 An…

MacOS本地部署Deepseek,不联网也可以使用AI,保护隐私

苹果笔记本本地部署deepseek主要用到Ollama与open-webui 1. 安装Ollama “Ollama” 是一个轻量级的 AI 模型运行时环境&#xff08;runtime&#xff09;&#xff0c;旨在简化在本地部署和使用大语言模型&#xff08;LLM&#xff09;的过程。它由 Vicarious 公司开发&#xff…

Golang笔记——Interface类型

大家好&#xff0c;这里是&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Golang的interface数据结构类型&#xff0c;包括基本实现和使用等。 文章目录 Go 语言中的 interface 详解接口定义实现接口空接口 interface{} 示例&…

docker容器网络配置及常用操作

Linux内核实现名称空间的创建 ip netns&#xff08;网络名称空间&#xff09;命令 可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包&#xff0c;一般系统会默认安装&#xff0c;如果没有的话&#xff0c;请自行安装。 注意&am…

leetcode - hot100 - python - 专题二:双指针

1、移动0 &#xff08;一句话概括题眼&#xff1a;右指针找非0元素&#xff09; 简单 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例…

【玩转 Postman 接口测试与开发2_020】(完结篇)DIY 实战:随书示例 API 项目本地部署保姆级搭建教程(含完整调试过程)

《API Testing and Development with Postman》最新第二版封面 文章目录 最新版《Postman 接口测试与开发实战》示例 API 项目本地部署保姆级搭建教程1 前言2 准备工作3 具体部署3.1 将项目 Fork 到自己名下3.2 创建虚拟环境并安装依赖3.3 初始运行与项目调试 4 示例项目的用法…

【第五节】C++设计模式(创建型模式)-Prototype(原型)模式

目录 一、问题背景 二、 模式选择 三、讨论总结 一、问题背景 在软件开发中&#xff0c;有时我们需要通过已有对象来创建新对象&#xff0c;而不是从头开始构建。这种需求让我想起了现代制造业中的 3D 打印技术。通过扫描一个现有的物体&#xff0c;3D 打印机可以快速复制出…

next.js-学习2

next.js-学习2 1. https://nextjs.org/learn/dashboard-app/getting-started2. 模拟的数据3. 添加样式4. 字体&#xff0c;图片5. 创建布局和页面页面导航 1. https://nextjs.org/learn/dashboard-app/getting-started /app: Contains all the routes, components, and logic …

OpenCV计算摄影学(1)图像修复(Inpainting)的函数inpaint()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 使用图像中选定区域的邻域来恢复该选定区域。 cv::inpaint 函数是 OpenCV 中用于图像修复&#xff08;Inpainting&#xff09;的一个重要函数。它…

北京智和信通:全方位智能 OLT、ONU 设备监控运维方案

随着网络技术的不断迭代与发展&#xff0c;OLT作为光纤接入网中的核心设备&#xff0c;负责管理多个ONU&#xff0c;实现数据的传输和分配。其监控与运维的重要性愈发凸显&#xff0c;为了确保网络运行的高效与稳定&#xff0c;选择一套全面且高效的OLT、ONU监控运维方案显得尤…

python-leetcode-搜索二维矩阵 II

240. 搜索二维矩阵 II - 力扣&#xff08;LeetCode&#xff09; class Solution:def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:if not matrix or not matrix[0]:return Falsem, n len(matrix), len(matrix[0])i, j 0, n - 1 # 从右上角开始whi…

推送项目 之 解决冲突

文章目录 为什么会发生冲突&#xff1f;如何解决这些冲突&#xff1f;1. **查看冲突文件**2. **解决二进制文件冲突**3. **解决文本文件冲突**4. **标记冲突已解决**5. **完成合并**6. **推送更改** 注意事项总结 问题&#xff1a;我们在git pusll拉取远程仓库的代码到本地对比…

网页版的俄罗斯方块

1、新建一个txt文件 2、打开后将代码复制进去保存 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>俄…

Docker 部署 Jenkins持续集成(CI)工具

[TOC](Docker 部署 Jenkins持续集成(CI)工具) 前言 Jenkins 是一个流行的开源自动化工具&#xff0c;广泛应用于持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;的环境中。通过 Docker 部署 Jenkins&#xff0c;可以简化安装和配置过程&#xff0c;并…

LLM+多智能体协作:基于CrewAI与DeepSeek的邮件自动化实践

文章目录 引言理解 Flows&#xff08;工作流&#xff09;与 Crews&#xff08;协作组&#xff09;一、环境准备与工具安装1.1 Python环境搭建1.2 创建并激活虚拟环境1.3 安装核心依赖库&#xff08;crewai、litellm&#xff09; 二、本地DeepSeek R1大模型部署2.1 Ollama框架安…

[SQL] 事务的四大特性(ACID)

&#x1f384;事务的四大特性 以下就是事务的四大特性&#xff0c;简称ACID。 原子性&#x1f4e2;事务时不可分割的最小操作单元&#xff0c;要么全部成功&#xff0c;要么全部失败。一致性&#x1f4e2;事务完成后&#xff0c;必须使所有的数据都保持一致隔离性&#x1f4e2…