【问题标题】:parsing API with Python - how to handle JSON with BOM使用 Python 解析 API - 如何使用 BOM 处理 JSON
【发布时间】:2016-03-29 15:10:13
【问题描述】:

我在 Windows 上使用 Python 2.7.11 从 API 获取 JSON 数据(波兰华沙的树木数据,但没关系)。我想使用 api 提供的所有数据生成输出 csv 文件,以供进一步分析。我从使用for another project 的脚本开始(在 Stackoverflow 上也进行了讨论,@Martin Taylor 为我更正了)。该脚本不起作用,所以我尝试使用我非常基本的理解对其进行修改,谷歌搜索并应用 pdb 调试器.目前,结果如下所示:

import pdb
import json
import urllib2
import csv

pdb.set_trace()
url = "https://api.um.warszawa.pl/api/action/datastore_search/?resource_id=ed6217dd-c8d0-4f7b-8bed-3b7eb81a95ba"
myfile = 'C:/dane/drzewa.csv'
csv_myfile = csv.writer(open(myfile, 'wb'))
cols = ['numer_adres', 'stan_zdrowia', 'y_wgs84', 'dzielnica', 'adres', 'lokalizacja', 'wiek_w_dni', 'srednica_k', 'pnie_obwod', 'miasto', 'jednostka', 'x_pl2000', 'wysokosc', 'y_pl2000', 'numer_inw', 'x_wgs84', '_id', 'gatunek_1', 'gatunek', 'data_wyk_pom']
csv_myfile.writerow(cols)       


def api_iterate(myfile):
    while True:
        global url
        print url
        json_page = urllib2.urlopen(url)
        data = json.load(json_page)
        json_page.close()

        for data_object in data ['result']['records']:
            csv_myfile.writerow([data_object[col] for col in cols])

        try:
            url = data['_links']['next']     
        except KeyError as e:
            break

with open(myfile, 'wb'):
    api_iterate(myfile)

我是一个非常新的 Python 用户,所以我一直很困惑。现在我明白了,在读取 json 字典中的对象时,我收到一条与“x_wgs84”元素关联的 Keyerror 消息。我想这与在源 url 中这个元素前面有一个 U+FEFF unicode 字符的事实有关。我试图解决这个问题,但我遇到了困难,希望得到帮助。

我怀疑代码可能以其他几种方式损坏 - 正如我所提到的,我是一个非常不熟练的程序员(但)。

【问题讨论】:

    标签: python json csv encoding


    【解决方案1】:

    您需要将密钥与 unicode 字符:

    要知道怎么做,一种简单的方法是打印密钥:

    >>> import requests
    >>> res = requests.get('https://api.um.warszawa.pl/api/action/datastore_search/?resource_id=ed6217dd-c8d0-4f7b-8bed-3b7eb81a95ba')
    >>> data = res.json()
    >>> records = data['result']['records']
    >>> records[0]
    {u'numer_adres': u'', u'stan_zdrowia': u'dobry', u'y_wgs84': u'52.21865', u'y_pl2000': u'5787241.04475524', u'adres': u'ul. ALPEJSKA', u'x_pl2000': u'7511793.96937063', u'lokalizacja': u'Ulica ALPEJSKA', u'wiek_w_dni': u'60', u'miasto': u'Warszawa', u'jednostka': u'Dzielnica Wawer', u'pnie_obwod': u'73', u'wysokosc': u'14', u'data_wyk_pom': u'20130709', u'dzielnica': u'Wawer', u'\ufeffx_wgs84': u'21.172584', u'numer_inw': u'D386200', u'_id': 125435, u'gatunek_1': u'Quercus robur', u'gatunek': u'd\u0105b szypu\u0142kowy', u'srednica_k': u'7'}
    >>> records[0].keys()
    [u'numer_adres', u'stan_zdrowia', u'y_wgs84', u'y_pl2000', u'adres', u'x_pl2000', u'lokalizacja', u'wiek_w_dni', u'miasto', u'jednostka', u'pnie_obwod', u'wysokosc', u'data_wyk_pom', u'dzielnica', u'\ufeffx_wgs84', u'numer_inw', u'_id', u'gatunek_1', u'gatunek', u'srednica_k']
    >>> records[0][u'\ufeffx_wgs84']
    u'21.172584'
    

    如您所见,要获取您的密钥,您需要将其写为 '\ufeffx_wgs84' 并使用引起问题的 unicode 字符。

    注意:我不知道您使用的是 python2 还是 3,但您可能需要在 python2 中的字符串声明之前放置 u 以将其声明为 unicode 字符串。 p>

    【讨论】:

    • 谢谢@Cybril,我已经试过了。如前所述,我使用的是 Python 2.7.11。我试图将 'x_wgs84' 转换为 '\ufeffx_wgs84' 但这并没有解决问题。错误响应也完全相同。我不确定你在字符串前加上'u'是什么意思——你是说'u'feffx_wgs_84'还是'u'\feffx_wgs_84'?这似乎也不起作用。
    • 看我的例子。 u 放在引号之前。
    • 对不起@Cybril,现在我明白了。这确实改变了一些东西,现在我在代码的第 7 行(url 定义)出现错误,说:UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 0: ordinal not in range (128) :) 也许是因为您使用了请求,正如我所读到的那样,它会自动处理一些编码问题..
    • 哦,是的,使用 urllib 您需要将结果解码为 UTF8。 (data.decode("utf8"))
    • 好的@Cybril 所以我应该把麻烦的键写成 u'\ufeffx_wgs84' 然后在 'data = json.load(json_page)' 之后插入 'data.decode("utf8")'?
    猜你喜欢
    • 2019-07-24
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2017-09-25
    • 1970-01-01
    • 2011-06-06
    • 2016-09-08
    相关资源
    最近更新 更多