-1

我有网站的 API 文档http://json-homework.task-sss.krasilnikov.spb.ru/docs/9f66a575a6cfaaf7e43177317461d057我要找到在某个城市的学校学习过的所有用户(其中​​ id 是 2) . 通过运行此代码(all_users包含上一个任务中有关用户的主要信息的列表):

school=[]
for user in all_users:
        user_id=user.get('id') 
        url = f'http://json-homework.task-sss.krasilnikov.spb.ru/api/user/get?api_key=9f66a575a6cfaaf7e43177317461d057&user_id={user_id}&fields=schools'
        data = rq.get(url)
        school=school+json.loads(data.text)["response"]
school

我得到了这样的数据(这是输出的一小部分,填充了许多字段):

 {'id': 136840302,
  'first_name': 'Marina',
  'last_name': 'Kushnir',
  'is_closed': False,
  'schools': [{'id': '352496',
    'country': 1,
    'city': 57,
    'name': 'Лицей ИГУ',
    'year_from': 2015,
    'year_to': 2019,
    'class': '',
    'type': 2,
    'type_str': 'Lyceum'}]},

所以我在参数'schools'中包含了一个参数'city',我只需要提取那些拥有这个参数的用户'city': 2。我也试过这段代码:

school=[]
for user in all_users:
    user_id=user.get('id') 
    url = f'http://json-homework.task-sss.krasilnikov.spb.ru/api/user/get?api_key=9f66a575a6cfaaf7e43177317461d057&user_id={user_id}&fields=schools'
    data = rq.get(url)
    school=school+json.loads(data.text)["response"]
school_norm=json_normalize(school)
schools = school_norm.get('schools')
school2=[]
for i in schools:
        if "'city' : 2" in i:
            school2.append(json.loads(data.text)["response"])
sch=pd.DataFrame(school2)

但它不接受这样的条件if "'city' : 2" in i:。那么我该怎么做这个任务呢?

我的第一个任务的代码是

all_users = []
for page in range(1,42):
    url=f'http://json-homework.task-sss.krasilnikov.spb.ru/api/groups/getmembers?api_key=9f66a575a6cfaaf7e43177317461d057&group_id=4508123&page={page}'
    data=rq.get(url)
    all_users = all_users + json.loads(data.text)["response"]
json_normalize(all_users)
group_data = pd.DataFrame(all_users, columns=['id','first_name','last_name']) 
group_data = group_data.sort_values('id')
group_data = group_data.set_index('id')
group_data 

和输出:数据框 所以在我上面写的任务的输出中,我需要得到类似于这个数据框,但只有那些有学校城市 id=2 的人,正如我之前解释的那样

4

1 回答 1

1

以下内容有点令人费解,但它至少应该让你离你想去的地方足够近。请注意,它假定您的数据采用有效的 json 格式(在您的问题中不是;您必须单独处理它 -请参阅此选项以修复格式错误的 json。

无论如何,鉴于此,我个人认为处理此类问题的最佳方法是使用 jsonpath for python。所以这里是:

假设您的数据由两个(有效的 json)组成,其中一个满足城市 id 为 2 的条件,另一个不满足:

schls ="""
[
  {
    "id": 136840302,
    "first_name": "Marina",
    "last_name": "Kushnir",
    "is_closed": "False,",
    "schools": [
      {
        "id": "352496",
        "country": 1,
        "city": 57,
        "name": "Лицей ИГУ",
        "year_from": 2015,
        "year_to": 2019,
        "class": "",
        "type": 2,
        "type_str": "Lyceum"
      }
    ]
  },
  {
    "id": 5555555555555,
    "first_name": "Marino",
    "last_name": "Kush",
    "is_closed": "False,",
    "schools": [
      {
        "id": "355556",
        "country": 1,
        "city": 2,
        "name": "Лице ИГ",
        "year_from": 2016,
        "year_to": 2018,
        "class": "",
        "type": 4,
        "type_str": "Lyceu"
      }
    ]
  }
]
"""

让我们处理数据:

import pandas as pd
import json
from jsonpath_ng import jsonpath, parse

data = json.loads(schls)
jsn_search = parse('$..schools') #this is your search string; looking for info in the "schools" entry
match = jsn_search.find(data) #search for the search string in the loaded json
schools = []
for m in match:
    if m.context.value.get('schools')[0].get('city')== 2: #this is your condition!
        schools.append(m.context.value) #condition met; append all surrounding info to list
df=pd.DataFrame(schools)
sch = df.drop(['is_closed' , 'schools'] , axis='columns')
sch

输出:

        id      first_name  last_name
0   5555555555555   Marino  Kush
于 2020-03-07T13:41:26.643 回答