【问题标题】:How to urlencode a querystring in Python?如何在 Python 中对查询字符串进行 urlencode?
【发布时间】:2011-08-02 05:28:38
【问题描述】:

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

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

【问题讨论】:

    标签: python urllib urlencode


    【解决方案1】:

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

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

    Python 3 或更高版本

    用途:

    >>> urllib.parse.urlencode(f)
    eventName=myEvent&eventDescription=cool+event
    

    请注意,这在常用意义上进行 url 编码(查看输出)。为此使用urllib.parse.quote_plus

    【讨论】:

    • "请注意,urllib.urlencode 并不总是有效。问题是某些服务关心参数的顺序,当您创建字典时会丢失。对于这种情况,urllib。正如 Ricky 建议的那样,quote_plus 更好。"
    • 从技术上讲,这是服务中的错误,不是吗?
    • 如果您只想使字符串 URL 安全,而不构建完整的查询参数字符串,该怎么做?
    • @Mike'Pomax'Kamermans -- 参见例如stackoverflow.com/questions/12082314/… 或 Ricky 对此问题的回答。
    • @bk0 看来你的方法只对字典有效,对字符串无效。
    【解决方案2】:

    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'
    

    Python 3

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

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

    【讨论】:

    • 谢谢!但就我而言,我需要输入:import urllib.parse ... urllib.parse.quote_plus(query)
    • 很好,但是为什么不习惯Unicode?如果url字符串是Unicode,我必须将它编码为UTF-8。还有其他方法吗?
    • 这很好用,但我无法访问一些在线服务 (REST),直到我添加了这个参数 safe=';/?:@&=+$,'
    • python3 -c "import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1])) "string to encode" 用于命令行上的一行
    • @AmosJoshua 我认为您在双圆括号)) 之后错过了双引号",它应该是:python3 -c "import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1]))" "string to encode"
    【解决方案3】:

    【讨论】:

    • 我自己更喜欢urllib.parse.quote(),因为它使用%20而不是+
    【解决方案4】:

    请注意,urllib.urlencode 并不总是有效。问题是一些服务关心参数的顺序,当你创建字典时它会丢失。对于这种情况,正如 Ricky 建议的那样, urllib.quote_plus 更好。

    【讨论】:

    • 如果您传递元组列表,它可以正常工作并保持顺序:>>> import urllib >>> urllib.urlencode([('name', 'brandon'), ('uid', 1000)]) 'name=brandon&uid=1000'
    【解决方案5】:

    供将来参考(例如:python3)

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

    【讨论】:

    • 通常您只想对值进行 url 编码,您在此处所做的操作会使 GET 查询无效
    • 'c:/2 < 3' 在 Windows 上的输出是 '///C://2%20%3C%203'。我想要一些只会输出'c:/2%20%3C%203'的东西。
    【解决方案6】:

    尝试使用requests 代替 urllib,您无需为 urlencode 烦恼!

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

    编辑:

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

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

    而不是使用字典。

    【讨论】:

    • 这并没有解决排序名称值对的问题,这也需要安装外部库的权限,这可能对项目不可行。
    • 我发布了适用于 OP 的最小代码。 OP 没有要求有序对,但它也是可行的,请参阅我的更新。
    • @dreftymac:这确实解决了订购问题(尽管它不是问题的一部分),请阅读我的更新答案。
    【解决方案7】:

    上下文

    • Python(2.7.2 版)

    问题

    • 您想要生成一个 urlencoded 查询字符串。
    • 您有一个包含名称-值对的字典或对象。
    • 您希望能够控制名称-值对的输出顺序。

    解决方案

    • urllib.urlencode
    • urllib.quote_plus

    陷阱

    示例

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

    ### ********************
    ## 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
      """ 
    

    【讨论】:

      【解决方案8】:

      试试这个:

      urllib.pathname2url(stringToURLEncode)
      

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

      【讨论】:

      • 这真的很有帮助!就我而言,我只有一部分字符串要进行 URL 编码,例如我想将 my string 转换为 my%20string。你的解决方案就像一个魅力!
      • 帮助我获得%20 而不是+。谢谢
      • 在 Python 3 中。现在是 urllib.request.pathname2url
      【解决方案9】:

      在 Python 3 中,这对我有用

      import urllib
      
      urllib.parse.quote(query)
      

      【讨论】:

        【解决方案10】:

        如果 urllib.parse.urlencode() 给你错误,那么试试 urllib3 模块。

        语法如下:

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

        【讨论】:

          【解决方案11】:

          另一件可能没有提到的事情是urllib.urlencode() 将字典中的空值编码为字符串None,而不是让该参数不存在。我不知道这是否通常需要,但不适合我的用例,因此我必须使用quote_plus

          【讨论】:

            【解决方案12】:

            对于需要同时支持python 2和3的脚本/程序,六模块提供了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】:

              对于 Python 3 urllib3 正常工作,您可以按照其official docs 如下使用:

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

              【讨论】:

                【解决方案14】:
                import urllib.parse
                query = 'Hellö Wörld@Python'
                urllib.parse.quote(query) // returns Hell%C3%B6%20W%C3%B6rld%40Python
                
                

                【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-07-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多