Итерация JSON в Python - PullRequest
       5

Итерация JSON в Python

0 голосов
/ 24 октября 2019

Я пытаюсь получить данные из API, который возвращает данные в виде объекта JSON. У меня есть вызов API, который возвращает данные, которые выглядят так (сокращенно для краткости)


   "status":"OK",
   "copyright":"Copyright (c) 2017 Pro Publica Inc. All Rights Reserved.",
   "results":[
      {
         "num_results": 10,
         "offset": 0,
         "bills": [
              {
                 "bill_id": "hr2739-113",
                 "bill_type": "hr",
                 "number": "H.R.2739",
                 "bill_uri": "https://api.propublica.org/congress/v1/113/bills/hr2739.json",
                 "title": "Efficient Use of Government Spectrum Act of 2013",
                 "sponsor_title": "Rep.",
                 "sponsor_id": "M001163",
                 "sponsor_name": "Doris Matsui",
                 "sponsor_state": "CA",
                 "sponsor_party": "D",
                 "sponsor_uri": "https://api.propublica.org/congress/v1/members/M001163.json",
                 "gpo_pdf_uri": "http://www.gpo.gov/fdsys/pkg/BILLS-113hr2739ih/pdf/BILLS-113hr2739ih.pdf",
                 "congressdotgov_url": "https://www.congress.gov/bill/113th-congress/house-bill/2739",
                 "govtrack_url": "https://www.govtrack.us/congress/bills/113/hr2739",
                 "introduced_date": "2013-07-18",
                 "committees": "House Armed Services Committee",
                 "committee_codes": ["HSAS","HSIF"],
                 "subcommittee_codes": ["HSAS26","HSIF16"],
                 "primary_subject": "Science, Technology, Communications",
                 "summary_short": "Efficient Use of Government Spectrum Act of 2013 - Directs the Federal Communications Commission (FCC), within three years after enactment of the Middle Class Tax Relief and Job Creation Act of 2012, to: (1) reallocate electromagnetic spectrum between the frequencies from 1755 to 1780 megahertz (currently, such frequencies are occupied by the Department of Defense [DOD] and other federal agencies); and (2) as part of the competitive bidding auctions required by such Act, grant new initial lic...",
                 "latest_major_action_date": "2013-08-29",
                 "latest_major_action": "Referred to the Subcommittee on Intelligence, Emerging Threats & Capabilities."
              },
                           {
                 "bill_id": "hr3355-113",
                 "bill_type": "hr",
                 "number": "H.R.3355",
                 "bill_uri": "https://api.propublica.org/congress/v1/113/bills/hr3355.json",
                 "title": "Reducing Employer Burdens, Unleashing Innovation, and Labor Development Act of 2013",
                 "sponsor_title": "Rep.",
                 "sponsor_id": "G000558",
                 "sponsor_name": "Brett Guthrie",
                 "sponsor_state": "KY",
                 "sponsor_party": "R",
                 "sponsor_uri": "https://api.propublica.org/congress/v1/members/G000558.json",
                 "gpo_pdf_uri": "http://www.gpo.gov/fdsys/pkg/BILLS-113hr3355ih/pdf/BILLS-113hr3355ih.pdf",
                 "congressdotgov_url": "https://www.congress.gov/bill/113th-congress/house-bill/3355",
                 "govtrack_url": "https://www.govtrack.us/congress/bills/113/hr3355",
                 "introduced_date": "2013-10-28",
                 "committees": "House Armed Services Committee",
                 "primary_subject": "Economics and Public Finance",
                 "summary_short": "Reducing Employer Burdens, Unleashing Innovation, and Labor Development Act of 2013 - Expresses the sense of Congress that increasing the competitiveness of U.S. manufacturers will strengthen the national economy. Title I: Investing in America's Workforce - Investing in America's Workforce Act - Amends the Workforce Investment Act of 1998 to require state or local workforce investment systems to use youth activities funds allocated to a local area for programs that provide training, which may...",
                 "latest_major_action_date": "2014-01-24",
                 "latest_major_action": "Referred to the Subcommittee on Intelligence, Emerging Threats & Capabilities."
              },

Используя Python, я пытаюсь перебрать данные и вернуть все значения следующим образом:

import requests
import json

r = requests.get({url and credentials here}).text

resp = json.loads(r)


for bill in resp['results']['bills']:
    name = bill['results']['bills']['title']
    type = item['results']['bills']['bill_type']

print(name, type)

Однако всякий раз, когда я пытаюсь запустить это, я получаю

TypeError: list indices must be integers or slices, not str

Почему я не могу использовать индексы списка в качестве str? Существует множество примеров использования ул.

Ответы [ 5 ]

4 голосов
/ 24 октября 2019

«Счета» в json - это список объектов (например, "bills" : [ - открывающая скобка квадратная, что подразумевает список).

Вы должны использовать целое число для доступа к элементусписок, так что вы можете сказать;

resp['results'][0]['bills'][0]

Для доступа к первому счету, например.

Тем не менее, ваш код немного запутан в вашем цикле, переменная bill будет содержать информацию для каждого счета, поэтому вы можете напрямую ссылаться на ключи, например, перебирать счета в первом результате

for bill in resp['results'][0]['bills']:
    name = bill['title']
    type = bill['bill_type']

    print(name, type)

Переменные 'name' и 'type' будут содержать только сведения о каждом счете во время цикла цикла.

Вы можете вкладывать циклы во все результаты

for result in resp['results']:
  for bill in result['bills']:
      name = bill['title']
      type = bill['bill_type']

      print(name, type)
0 голосов
/ 24 октября 2019

Если вы получаете ответ JSON, найдите ниже два способа его анализа.

Метод 1: Обычный способ - это то, что вы пытаетесь

import requests


resp = requests.get(url="url",auth="cred").json()

for bill in resp['results'][0]['bills']:
    bill_name = bill['title']
    bill_type = bill['bill_type']

print(bill_name, bill_type)

Метод 2: Очистительподход к получению ответа json

for bill_dict in resp.get("results", []):  # returns None if "results" field is not found
    for bill in bill_dict.get('bills', []): 
        bill_name = bill.get('title')  # None is assigned to bill_name if key 'title' is not found
        bill_type = bill.get('bill_type')  # None is assigned to bill_name if key 'title' is not found error OR you can assign default value if key is not found Ex: bill.get('bill_type', 'bill type unavailable')

print(bill_name, bill_type)

Есть и много других способов.

0 голосов
/ 24 октября 2019

также в вашем коде, имя равно:

name = bill['results']['bills']['title'] -> resp['results']['bills']['results']['bills']['title']
0 голосов
/ 24 октября 2019

В данных json results - список диктов. Итак, сначала переберите результаты. Затем для каждого результата выполните итерацию по счетам, чтобы получить название и тип счета.

for result in resp['results']:
    for bill in result['bills']:
        name = bill['title']
        type = item['bill_type']
        print(name, type)
0 голосов
/ 24 октября 2019

bill - это объект json, который не имеет results или bills в качестве строкового индекса. Попробуйте следующее:

for bill in resp['results']['bills']:
    name = bill['title']
    type = item['bill_type']

    print(name, type)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...