用python导入API json数据并转换为csv格式导出到Excel中

1 人不认可

我在一家物业公司工作,正试图创建一个经常更新的excel表,其中包含公司所有的单位/租户/物业/等数据。我们目前使用一个物业管理网站,其中包含我们所有的数据。该网站有一个api,我应该可以用它来访问这些数据。

我已经尝试从网站的api导入数据,并且已经成功导入了。话虽如此,但导入的数据只有json文件的格式,我在将其转换为csv时遇到了麻烦。

以下是我目前的计划。

'''all imports needed'''
import requests
import pandas as pd
import csv
import json
#get data from api
url ='https://*apiusername:apisecretkey@companyname*.appfolio.com/api/v1/reports/rent_roll.json?columns=Property,PropertyName,PropertyGroupId,PropertyAddress,Unit,Tenant,BdBa,SquareFt,MarketRent,Rent,MoveIn,MoveOut'
    response = requests.get(url).json()
    print("successfully imported json data from appfolio api.")
except IOError:
    print("I/O Error")
#flatten json dictionary just in case
def flattenjson(b, delim):
    print("attempting to flatten json dictionary.")
    val = {}
    for i in b.keys():
        if isinstance(b[i], dict):
            get = flattenjson(b[i], delim)
            for j in get.keys():
                val[i+ delim + j]= get[j]
        else:
            val[i] = b[i]
    return val
test = flattenjson(response, ',')
#print output for test
print(test)
#confirm that test variable is in dictionary format
if isinstance(test, dict):
    print("your imported file is a dictionary.")
#convert dictionary to a csv with pandas
    df = pd.DataFrame.from_dict(test)
    print("converted dictionary to pandas dataframe.\n\n")
except:
    print("Error")
    df.to_csv("data.csv")
    print("successfully converted dataframe to csv file. attempting to read back data.\n\n")
    df = pd.read_csv("data.csv", index_col=0)
    print(df)
except:
    print("Error")

如果我在将导入的json字典转换为csv之前打印出来,这是一个当前结构的样本,它看起来像什么。

{'结果':[{'物业':'1020p - 1024 N. roadname Pkwy.Cityname, XX 12345', 'PropertyName': '1020p', 'PropertyGroupId': '418024, 418031, 418057, 418068, 418069, 418073, 418077', 'PropertyAddress': '1020 N. roadname Pkwy. roadname Pkwy.Cityname, XX 12345', '单元': '商业-Loop Lofts B单元', '租户':None, 'BdBa': '--/-', 'SquareFt': '4,888', MarketRent': '4,000.00', '租金':无, 'MoveIn':无, 'MoveOut': 无}, {'Property':'1020p - 1024 N. roadname Pkwy.Cityname, XX 12345, 'PropertyName': '1020p', 'PropertyGroupId': '418024, 418031, 418057, 418068, 418069, 418073, 418077', 'PropertyAddress': '1020 N. roadname Pkwy. roadname Pkwy.Cityname, XX 12345', '单元': '100', '租户': 'John Roberts', 'BdBa': '1/1.00', 'SquareFt': '930', 'MarketRent': 1,075.00', '租金': '1,075.00', '迁入': '10/17/2021', '迁出': 无}], '下一步_页面_url':无}。

我相信,由于API的工作方式,它正在制作一个嵌套的字典,第一个键被标为results,而最后一个键被标记为下一步_页面_url.

由于这个原因,我相信当用pandas把字典转换为csv时,它把我所有必须处理属性数据的键放在他们自己的列中。而这是我想改变的事情。我目前转换的csv输出看起来是这样的。

    results  next_page_url                      
 0    {'Property': '1020p - 1024 N. roadname Pkwy. St...           NaN
 1    {'Property': '1020p - 1024 N. roadname Pkwy. St...           NaN
 2    {'Property': '1020p - 1024 N. roadname Pkwy. St...           NaN
 3    {'Property': '1020p - 1024 N. roadname Pkwy. St...           NaN
 4    {'Property': '1020p - 1024 N. roadname Pkwy. St...           NaN
 ..                                                 ...            ...
 639  {'Property': 'putinvest - 4240 something Ave....             NaN
 640  {'Property': 'putmgr - 4240 something Ave. St...             NaN
 641  {'Property': 'z4184p - 4184 Something Ave. Jo...             NaN
 642  {'Property': 'z4400p - 4400 Boardwalk Name  St. ...          NaN
 643  {'Property': 'z4514 - 4514 something Ave. St. Lo...          NaN
 [644 rows x 2 columns]

理想情况下,来自api的每一列,如PropertyName、Tenant、PropertyAddress等,在csv中都有自己的列。谁能告诉我如何以这种方式进行格式化?

1 个评论
df = pd.DataFrame(response['results'])
python
json
pandas
api
csv
pizzleberry
pizzleberry
发布于 2021-12-22
2 个回答
Antoine
Antoine
发布于 2021-12-22
0 人赞同

你在最后的CSV中需要 next_page_url 吗?

Did you try doing this ?

df = pd.DataFrame(test["results"])
    
不,我不需要nextpageurl。api文档指出,结果是分页的。但我相信文档中提供了一个字符串,你可以附加到url上,以使它不分页。我很快就会试一下。 我也没有尝试你列出的方法。我不知道我可以用字典中的一个特定的键来创建一个数据框,所以谢谢你!
Parker.V
Parker.V
发布于 2021-12-22
0 人赞同

我对那个.json例子中使用的格式有困难,但实际上你可以用你导入的json库来解决这个问题,这是个更简单的方法。

我通常是通过保存请求响应来进行的。

response = requests.request("GET", new_url, headers=headers, data=payload)

然后我使用.load()函数,将其加载到一个Python dict中,然后你可以对其进行索引。

results = json.loads(response.text)['results'][0]

will give you

[{'物业':'1020p - 1024 N. roadname Pkwy.Cityname, XX 12345', PropertyName': '1020p', 'PropertyGroupId': '418024, 418031, 418057, 418068, 418069, 418073, 418077', 'PropertyAddress': '1020 N. roadname Pkwy.Cityname, XX 12345', '单元': '商业-Loop Lofts单元B', '租户':None, 'BdBa': '--/-', 'SquareFt': '4,888', 'MarketRent': '4,000.00', '租金':无, 'MoveIn':无, 'MoveOut':无}。 {'物业':'1020p - 1024 N. roadname Pkwy.Cityname, XX 12345, PropertyName': '1020p', 'PropertyGroupId': '418024, 418031, 418057, 418068, 418069, 418073, 418077', 'PropertyAddress': '1020 N. roadname Pkwy.Cityname, XX 12345', '单元': '100', '租户': 'John Roberts', 'BdBa': '1/1.00', 'SquareFt': '930', 'MarketRent': '1,075.00', 'Rent':