如何在 Python 中对查询字符串进行 urlencode 编码?

2024-12-18 08:39:00
admin
原创
127
摘要:问题描述:我在提交之前尝试对这个字符串进行 urlencode 编码。queryString = 'eventName=' + evt.fields["eventName"] + '&' + 'eventDescription=' + evt.fields["eventD...

问题描述:

我在提交之前尝试对这个字符串进行 urlencode 编码。

queryString = 'eventName=' + evt.fields["eventName"] + '&' + 'eventDescription=' + evt.fields["eventDescription"]; 

解决方案 1:

Python 3

在 Python 3 中,该urllib包被分解为更小的组件。您将使用urllib.parse.quote_plus(注意parse子模块)

import urllib.parse
safe_string = urllib.parse.quote_plus(...)

Python 2

您正在寻找的是urllib.quote_plus

safe_string = urllib.quote_plus('string_of_characters_like_these:$#@=?%^Q^$')

#Value: 'string_of_characters_like_these%3A%24%23%40%3D%3F%25%5EQ%5E%24'

解决方案 2:

Python 3

使用urllib.parse.urlencode

>>> import urllib.parse
>>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'}
>>> urllib.parse.urlencode(f)
eventName=myEvent&eventDescription=cool+event

请注意,这不会执行通常意义上的 URL 编码(请查看输出)。为此请使用urllib.parse.quote_plus

Python 2

您需要将参数urllib.urlencode()作为映射(字典)或2元组序列传递,例如:

>>> import urllib
>>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'}
>>> urllib.urlencode(f)
'eventName=myEvent&eventDescription=cool+event'

解决方案 3:

尝试使用请求而不是 urllib,您就不需要担心 urlencode!

import requests
requests.get('http://youraddress.com', params=evt.fields)

编辑:

如果您需要有序的名称-值对或名称的多个值,则请像这样设置参数:

params=[('name1','value11'), ('name1','value12'), ('name2','value21'), ...]

而不是使用字典。

解决方案 4:

语境

  • Python(版本 2.7.2)

问题

  • 您想要生成一个 urlencoded 的查询字符串。

  • 您有一个包含名称-值对的字典或对象。

  • 您希望能够控制名称-值对的输出顺序。

解决方案

  • urllib.urlencode

  • urllib.quote_plus

陷阱

  • 字典输出名称-值对的任意顺序

    • (另请参阅:为什么 Python 如此排列我的字典?)

    • (另请参阅:为什么字典和集合的顺序是任意的?)

  • 处理不关心名称-值对顺序的情况

  • 当你确实关心名称-值对的顺序时的处理情况

  • 处理单个名称需要在所有名称-值对集合中出现多次的情况

例子

下面是完整的解决方案,包括如何处理一些陷阱。

### ********************
## init python (version 2.7.2 )
import urllib

### ********************
## first setup a dictionary of name-value pairs
dict_name_value_pairs = {
  "bravo"   : "True != False",
  "alpha"   : "http://www.example.com",
  "charlie" : "hello world",
  "delta"   : "1234567 !@#$%^&*",
  "echo"    : "user@example.com",
  }

### ********************
## setup an exact ordering for the name-value pairs
ary_ordered_names = []
ary_ordered_names.append('alpha')
ary_ordered_names.append('bravo')
ary_ordered_names.append('charlie')
ary_ordered_names.append('delta')
ary_ordered_names.append('echo')

### ********************
## show the output results
if('NO we DO NOT care about the ordering of name-value pairs'):
  queryString  = urllib.urlencode(dict_name_value_pairs)
  print queryString 
  """
  echo=user%40example.com&bravo=True+%21%3D+False&delta=1234567+%21%40%23%24%25%5E%26%2A&charlie=hello+world&alpha=http%3A%2F%2Fwww.example.com
  """

if('YES we DO care about the ordering of name-value pairs'):
  queryString  = "&".join( [ item+'='+urllib.quote_plus(dict_name_value_pairs[item]) for item in ary_ordered_names ] )
  print queryString
  """
  alpha=http%3A%2F%2Fwww.example.com&bravo=True+%21%3D+False&charlie=hello+world&delta=1234567+%21%40%23%24%25%5E%26%2A&echo=user%40example.com
  """ 

解决方案 5:

Python 3:

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

解决方案 6:

尝试一下:

urllib.pathname2url(stringToURLEncode)

urlencode不起作用,因为它只适用于字典。quote_plus没有产生正确的输出。

解决方案 7:

请注意,urllib.urlencode 并不总是有效。问题在于某些服务关心参数的顺序,而创建字典时会丢失这些顺序。对于这种情况,Ricky 建议使用 urllib.quote_plus。

解决方案 8:

在 Python 3 中,这个对我有用

import urllib

urllib.parse.quote(query)

解决方案 9:

import urllib.parse
query = 'Hellö Wörld@Python'
urllib.parse.quote(query) # returns Hell%C3%B6%20W%C3%B6rld%40Python

解决方案 10:

供将来参考(例如:python3)

>>> import urllib.request as req
>>> query = 'eventName=theEvent&eventDescription=testDesc'
>>> req.pathname2url(query)
>>> 'eventName%3DtheEvent%26eventDescription%3DtestDesc'

解决方案 11:

如果 urllib.parse.urlencode() 出现错误,请尝试 urllib3 模块。

语法如下

import urllib3
urllib3.request.urlencode({"user" : "john" }) 

解决方案 12:

为了在需要同时支持 Python 2 和 3 的脚本/程序中使用,six 模块提供了 quote 和 urlencode 函数:

>>> from six.moves.urllib.parse import urlencode, quote
>>> data = {'some': 'query', 'for': 'encoding'}
>>> urlencode(data)
'some=query&for=encoding'
>>> url = '/some/url/with spaces and %;!<>&'
>>> quote(url)
'/some/url/with%20spaces%20and%20%25%3B%21%3C%3E%26'

解决方案 13:

另一件可能尚未提及的事情是,它将urllib.urlencode()把字典中的空值编码为字符串,None而不是将该参数视为缺失。我不知道这是否是通常需要的,但不适合我的用例,因此我必须使用quote_plus

解决方案 14:

对于 Python 3 urllib3正常工作,您可以根据其官方文档进行如下使用:

import urllib3

http = urllib3.PoolManager()
response = http.request(
     'GET',
     'https://api.prylabs.net/eth/v1alpha1/beacon/attestations',
     fields={  # here fields are the query params
          'epoch': 1234,
          'pageSize': pageSize 
      } 
 )
response = attestations.data.decode('UTF-8')

解决方案 15:

如果您不想使用 urllib。

https://github.com/wayne931121/Python_URL_Decode

URL_RFC_3986 = {
"!": "%21", "#": "%23", "$": "%24", "&": "%26", "'": "%27", "(": "%28", ")": "%29", "*": "%2A", "+": "%2B", 
",": "%2C", "/": "%2F", ":": "%3A", ";": "%3B", "=": "%3D", "?": "%3F", "@": "%40", "[": "%5B", "]": "%5D",
}

def url_encoder(b):
    # https://zh.wikipedia.org/wiki/%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81
    if type(b)==bytes:
        b = b.decode(encoding="utf-8") #byte can't insert many utf8 charaters
    result = bytearray() #bytearray: rw, bytes: read-only
    for i in b:
        if i in URL_RFC_3986:
            for j in URL_RFC_3986[i]:
                result.append(ord(j))
            continue
        i = bytes(i, encoding="utf-8")
        if len(i)==1:
            result.append(ord(i))
        else:
            for c in i:
                c = hex(c)[2:].upper()
                result.append(ord("%"))
                result.append(ord(c[0:1]))
                result.append(ord(c[1:2]))
    result = result.decode(encoding="ascii")
    return result

#print(url_encoder("我好棒==%%0.0:)")) ==> '%E6%88%91%E5%A5%BD%E6%A3%92%3D%3D%%0.0%3A%29'

解决方案 16:

就我的情况而言,urllib parse 还不够。

需要添加两项内容:

  1. 使用safekwarg 取消标记/为安全字符 ( urllib.parse.quote(string, safe=''))

  2. 使用 .replace() 替换剩余的特殊字符 - 特别注意,javascript 的 encodeURIComponent 和 C# Uri.EscapeDataString 的行为不同。要使用需要 EscapeDataStrings 的 C# 后端,则需要额外替换以下内容:_-.~

最终我有这样的东西

import urllib

def aggressive_urlencode(inp: str) -> str:
    return (
        urllib.parse.quote(inp, safe='')
        .replace('-', '%2D')
        .replace('.', '%2E')
        .replace('_', '%5F')
        .replace('~', '%7E')
    )
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用