前端補充:url編碼

Xiao0101發表於2024-04-09

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

# 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))

# 請輸入要搜尋的內容:爬蟲
# http://www.baidu.com/s?wd=%E7%88%AC%E8%99%AB

注意:

​ 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)

相關文章