当前位置: 首页 > news >正文

URL编码解码详解

URL编码/解码详解

当 URL 路径或者查询参数中,带有中文或者特殊字符的时候,就需要对 URL 进行编码(采用十六进制编码格式)。URL 编码的原则是使用安全字符去表示那些不安全的字符。

安全字符,指的是没有特殊用途或者特殊意义的字符。

URL基本组成

URL 是由一些简单的组件构成,比如协议、域名、端口号、路径和查询字符串等,示例如下:

http://www.ccc.net/index?param=10

路径和查询字符串之间使用问号隔开。上述示例的域名为 www.ccc.net,路径为 index,查询字符串为 param=1。

URL 中规定了一些具有特殊意义的字符,常被用来分隔两个不同的 URL 组件,这些字符被称为保留字符。例如:

冒号:用于分隔协议和主机组件,斜杠用于分隔主机和路径

:用于分隔路径和查询参数等。

=用于表示查询参数中的键值对。

&符号用于分隔查询多个键值对。

其余常用的保留字符有:/ . … # @ $ + ; %

哪些字符需要编码

URL 之所以需要编码,是因为 URL 中的某些字符会引起歧义,比如 URL 查询参数中包含了”&”或者”%”就会造成服务器解析错误;再比如,URL 的编码格式采用的是 ASCII 码而非 Unicode 格式,这表明 URL 中不允许包含任何非 ASCII 字符(比如中文),否则就会造成 URL 解析错误。

URL 编码协议规定(RFC3986 协议):URL 中只允许使用 ASCII 字符集可以显示的字符,比如英文字母、数字、和- _ . ~ ! *这 6 个特殊字符。当在 URL 中使用不属于 ASCII 字符集的字符时,就要使用特殊的符号对该字符进行编码,比如空格需要用%20来表示。

除了无法显示的字符需要编码外,还需要对 URL 中的部分保留字符和不安全字符进行编码。下面列举了部分不安全字符:

[ ] < > " " { } | ^ * · ‘ ’ 等

下面示例,查询字符串中包含一些特殊字符,这些特殊字符不需要编码:

http://www.ccc.net/index?param=10!*&param1=20!-~_

下表对 URL 中部分保留字符和不安全字符进行了说明:

URL特殊字符编码

字符

含义

十六进制值编码

URL 中 + 号表示空格

%2B

空格

URL中的空格可以编码为 + 号或者 %20

%20

/

分隔目录和子目录

%2F

分隔实际的 URL 和参数

%3F

%

指定特殊字符

%25

表示书签

%23

&

URL 中指定的参数间的分隔符

%26

=

URL 中指定参数的值

%3D

下面简单总结一下,哪些字符需要编码,分为以下三种情况:

ASCII 表中没有对应的可显示字符,例如,汉字。 不安全字符,包括:# ”% <> [] {} | ^ ` 。 部分保留字符,即 &
/ : ; = @ 。

Python实现编码与解码

Python 的标准库urllib.parse模块中提供了用来编码和解码的方法,分别是 urlencode() 与 unquote() 方法。

方法

说明

urlencode()

该方法实现了对 url 地址的编码操作

unquote()

该方法将编码后的 url 地址进行还原,被称为解码

1) 编码urlencode()

下面以百度搜索为例进行讲解。首先打开百度首页,在搜索框中输入“爬虫”,然后点击“百度一下”。当搜索结果显示后,此时地址栏的 URL 信息,如下所示:

https://www.baidu.com/s?wd=爬虫&rsv_spt=1&rsv_iqid=0xa3ca348c0001a2ab&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ib&rsv_sug3=8&rsv_sug1=7&rsv_sug7=101

可以看出 URL 中有很多的查询字符串,而第一个查询字符串就是“wd=爬虫”,其中 wd 表示查询字符串的键,而“爬虫”则代表您输入的值。

在网页地址栏中删除多余的查询字符串,最后显示的 URL 如下所示:

https://www.baidu.com/s?wd=爬虫

使用搜索修改后的 URL 进行搜索,依然会得到相同页面。因此可知“wd”参数是百度搜索的关键查询参数。下面编写爬虫程序对 “wd=爬虫”进行编码,如下所示:

#导入parse模块
from urllib import parse
#构建查询字符串字典
query_string = {
'wd' : '爬虫'
}
#调用parse模块的urlencode()进行编码
result = parse.urlencode(query_string)
#使用format函数格式化字符串,拼接url地址
url = 'http://www.baidu.com/s?{}'.format(result)
print(url)

输出结果,如下所示:

wd=%E7%88%AC%E8%99%AB
http://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB

编码后的 URL 地址依然可以通过地网页址栏实现搜索功能。

除了使用 urlencode() 方法之外,也可以使用 quote(string) 方法实现编码,代码如下:

from urllib import parse
#注意url的书写格式,和 urlencode存在不同
url = 'http://www.baidu.com/s?wd={}'
word = input('请输入要搜索的内容:')
#quote()只能对字符串进行编码
query_string = parse.quote(word)
print(url.format(query_string))

输出结果如下:

输入:请输入要搜索的内容:编程帮www.biancheng.net
输出:http://www.baidu.com/s?wd=%E7%BC%96%E7%A8%8B%E5%B8%AEwww.biancheng.net

注意:quote() 只能对字符串编码,而 urlencode() 可以直接对查询字符串字典进行编码。因此在定义 URL 时,需要注意两者之间的差异。方法如下:

# urllib.parse
urllib.parse.urlencode({'key':'value'}) #字典
urllib.parse.quote(string) #字符串

2) 解码unquote(string)
解码是对编码后的 URL 进行还原的一种操作,示例代码如下:

from urllib import parse
string = '%E7%88%AC%E8%99%AB'
result = parse.unquote(string)
print(result)

输出结果:

爬虫

3) URL地址拼接方式
最后,给大家介绍三种拼接 URL 地址的方法。除了使用 format() 函数外,还可以使用字符串相加,以及字符串占位符,总结如下:
纯文本复制

# 1、字符串相加
  baseurl = 'http://www.baidu.com/s?'
  params='wd=%E7%88%AC%E8%99%AB'
  url = baseurl + params
# 2、字符串格式化(占位符)
  params='wd=%E7%88%AC%E8%99%AB'
  url = 'http://www.baidu.com/s?%s'% params
# 3、format()方法
  url = 'http://www.baidu.com/s?{}'
  params='wd=%E7%88%AC%E8%99%AB'
  url = url.format(params)

最后

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。

相关文章:

  • win10+ubuntu双系统下载ubuntu方法(卸载系统不完整会进入grub)
  • Spring事务传播机制
  • 实现深度理解函数指针
  • C/C++常用预编译指令介绍
  • 杰理强制升级工具4.0使用和原理解析
  • Vue3介绍和安装
  • Linux命令--权限(chmod、chown)--使用/实例
  • flink-sql所有语法详解
  • 【图像分割】基于matlab萤火虫算法图像聚类分割【含Matlab源码 2106期】
  • SQL 入门之第一讲——MySQL 8.0.29安装教程(windows 64位)
  • 用Python进行数学建模(一)
  • 力扣:669. 修剪二叉搜索树,今日份快乐
  • java毕业设计KTV点歌系统mybatis+源码+调试部署+系统+数据库+lw
  • [python] 基于diagrams库绘制系统架构图
  • 2022 年全国职业院校技能大赛(中职组) 网络安全竞赛试题D模块评分标准
  • Android组件 - 收藏集 - 掘金
  • docker-consul
  • ES6系列(二)变量的解构赋值
  • es的写入过程
  • extjs4学习之配置
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS实现简单的MVC模式开发小游戏
  • TypeScript实现数据结构(一)栈,队列,链表
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 如何编写一个可升级的智能合约
  • ​批处理文件中的errorlevel用法
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • (1)STL算法之遍历容器
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (强烈推荐)移动端音视频从零到上手(上)
  • (三十五)大数据实战——Superset可视化平台搭建
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (一一四)第九章编程练习
  • ***检测工具之RKHunter AIDE
  • .NET : 在VS2008中计算代码度量值
  • .NET Core Web APi类库如何内嵌运行?
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET Project Open Day(2011.11.13)
  • .NET 材料检测系统崩溃分析
  • .NET 中让 Task 支持带超时的异步等待
  • .NetCore项目nginx发布
  • :not(:first-child)和:not(:last-child)的用法
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • @Not - Empty-Null-Blank
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [20140403]查询是否产生日志
  • [20170705]diff比较执行结果的内容.txt
  • [20170728]oracle保留字.txt
  • [30期] 我的学习方法
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [AutoSar]BSW_Com07 CAN报文接收流程的函数调用