首页 > 解决方案 > Python - 使用相同的键提取多个 json

问题描述

所以我正在加载一个包含代理的 JSON 文件,

我的 JSON 对象。

 {  
   "http":{  
      "http://":"64.90.50.38:45876/",
      "http://":"89.250.220.40:54687/",
      "http://":"89.207.92.146:37766/",
      "http://":"89.23.194.174:8080/",
      "http://":"82.208.111.100:52480/"
   }
}

我想访问每个代理,但我不断获得最后一个代理,即“http://”:“82.208.111.100:52480/

我的代码:

import json
x = open('proxy.json', 'r')
data = json.load(x)
print data['http']

我的问题是:如何使用相同的键访问这些值?

标签: pythonjson

解决方案


根据文档

RFC 规定 JSON 对象中的名称应该是唯一的,但没有规定如何处理 JSON 对象中的重复名称。默认情况下,此模块不会引发异常;相反,它会忽略给定名称的最后一个名称-值对以外的所有内容:

>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}

object_pairs_hook参数可用于更改此行为。

文档还声明这object_pairs_hook是一个可选函数,将调用任何对象文字的结果,并使用有序的对列表进行解码。将使用的返回值object_pairs_hook代替 dict。此功能可用于实现自定义解码器。如果object_hook还定义了,object_pairs_hook则优先。

例如,

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> from collections import defaultdict
>>> from pprint import pprint
>>>
>>> s = """
... {
...    "http":{
...       "http://":"64.90.50.38:45876/",
...       "http://":"89.250.220.40:54687/",
...       "http://":"89.207.92.146:37766/",
...       "http://":"89.23.194.174:8080/",
...       "http://":"82.208.111.100:52480/"
...    }
... }
... """
>>>
>>> def custom_hook(obj):
...     # Identify dictionary with duplicate keys...
...     # If found create a separate dict with single key and val and as list.
...     if len(obj) > 1 and len(set(i for i, j in obj)) == 1:
...         data_dict = defaultdict(list)
...         for i, j in obj:
...             data_dict[i].append(j)
...         return dict(data_dict)
...     return dict(obj)
...
>>> data = json.loads(s, object_pairs_hook=custom_hook)
>>> pprint(data)
{'http': {'http://': ['64.90.50.38:45876/',
                      '89.250.220.40:54687/',
                      '89.207.92.146:37766/',
                      '89.23.194.174:8080/',
                      '82.208.111.100:52480/']}}
>>>
>>> pprint(data['http'])
{'http://': ['64.90.50.38:45876/',
             '89.250.220.40:54687/',
             '89.207.92.146:37766/',
             '89.23.194.174:8080/',
             '82.208.111.100:52480/']}

推荐阅读