【问题标题】:Why I can't use urlencode to encode json format data?为什么我不能使用 urlencode 对 json 格式数据进行编码?
【发布时间】:2012-01-07 18:01:24
【问题描述】:

我在 python 2.7 中遇到了关于 urlencode 的问题:

>>> import urllib
>>> import json
>>> urllib.urlencode(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/urllib.py", line 1280, in urlencode
    raise TypeError
TypeError: not a valid non-string sequence or mapping object

【问题讨论】:

    标签: python json urlencode python-2.7


    【解决方案1】:

    (1) 导入库

    import requests
    import json
    

    (2) Spec是一个字典对象

    spec = {...}
    

    (3) 将字典对象转换为json

    data = json.dumps(spec, ensure_ascii=False)
    

    (4) 最后用json格式的参数spec做请求

    response = requests.get(
        'http://localhost:8080/...',
        params={'spec': data}
    )
    

    (5) 分析响应...

    【讨论】:

      【解决方案2】:

      对于那些你会得到错误的人:

      AttributeError: 模块 'urllib' 没有属性 'urlencode'

      这是因为urllib 在 Python 3 中被拆分了


      这是 Python 3 的代码:

      import urllib.parse
      
      data = {
          "title": "Hello world",
          "anonymous": False,
          "needautocategory": True
      }
      
      urllib.parse.urlencode(data)
      # 'title=Hello+world&anonymous=False&needautocategory=True'
      

      【讨论】:

      • 在 Python 3 上为我工作。
      【解决方案3】:

      json.dumps() 返回一个字符串。

      urllib.urlencode() 需要一个映射对象或元组格式的查询。请注意,它不需要字符串。

      您将第一个作为第二个的参数传递,导致错误。

      【讨论】:

        【解决方案4】:

        urlencode 可以编码字典,但不能编码字符串。 json.dumps 的输出是一个字符串。

        根据您想要的输出,不要在 JSON 中对字典进行编码:

        >>> urllib.urlencode({'title':"hello world!",'anonymous':False,'needautocategory':True})
        'needautocategory=True&anonymous=False&title=hello+world%EF%BC%81'
        

        或将整个内容包装在一个字典中:

        >>> urllib.urlencode({'data': json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True})})
        'data=%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D'
        

        或使用quote_plus() 代替(urlencode 使用quote_plus 作为键和值):

        >>> urllib.quote_plus(json.dumps({'title':"hello world!",'anonymous':False,'needautocategory':True}))
        '%7B%22needautocategory%22%3A+true%2C+%22anonymous%22%3A+false%2C+%22title%22%3A+%22hello+world%5Cuff01%22%7D'
        

        【讨论】:

        • 请注意quote_plus() 将转换您在+ 中的空间。在处理 JSON 时,您可能希望将它们保留为 %20,为此使用 quote()
        【解决方案5】:

        因为urllib.urlencode"converts a mapping object or a sequence of two-element tuples to a “percent-encoded” string..."。你的字符串不是这些。

        我认为你需要urllib.quoteurllib.quote_plus

        【讨论】:

        • 这不适用于 Python 3。对于 python3,urllib 被拆分为几个模块。我们需要使用urllib.parse.urlencode
        猜你喜欢
        • 2013-03-12
        • 2019-02-11
        • 2012-10-06
        • 1970-01-01
        • 2013-01-21
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多