Python-从嵌套json提取数据时出现问题

时间:2019-08-29 07:49:50

标签: python json python-jsons

我从json提取数据时遇到问题,我尝试了n种不同的方法。我能够提取ID本身,但是不幸的是,我无法显示该字段的详细信息。
下面是我的json

{
    "params": {
        "cid": "15482782896",
        "datemax": "20190831",
        "datemin": "20190601",
        "domains": [
            "url.com"
        ],

    },
    "results": {
        "59107": {
            "url.com": {
                "1946592": {
                    "data": {
                        "2019-06-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 21,
                                        "url": "url3.com"
                                    }
                                }
                            }
                        },
                        "2019-07-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 4,
                                        "url": "url3.com"
                                    }
                                }
                            }
                        },
                        "2019-08-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 2,
                                        "url": "url3.com"
                                    }
                                }
                            }
                        }
                    },
                    "keyword": {
                        "title": "python_1",
                        "volume": 10
                    }
                },
                "1946602": {
                    "data": {
                        "2019-06-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 5,
                                        "url": "url1.com"
                                    }
                                }
                            }
                        },
                        "2019-07-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 12,
                                        "url": "url1.com"
                                    }
                                }
                            }
                        },
                        "2019-08-01": {
                            "ENGINE": {
                                "DEVICE": {
                                    "": {
                                        "position": 10.25,
                                        "url": "url1.com"
                                    }
                                }
                            }
                        }
                    },
                    "keyword": {
                        "title": "python_2",
                        "volume": 20
                    }
                }
            }
        }
    }
}

我尝试了以下代码,但以id本身的形式得到了结果

import json
import csv

def get_leaves(item, key=None):
    if isinstance(item, dict):
        leaves = {}
        for i in item.keys():
            leaves.update(get_leaves(item[i], i))
        return leaves
    elif isinstance(item, list):
        leaves = {}
        for i in item:
            leaves.update(get_leaves(i, key))
        return leaves
    else:
        return {key : item}


with open('me_filename') as f_input:
    json_data = json.load(f_input)

fieldnames = set()

for entry in json_data:
    fieldnames.update(get_leaves(entry).keys())

with open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.DictWriter(f_output, fieldnames=sorted(fieldnames))
    csv_output.writeheader()
    csv_output.writerows(get_leaves(entry) for entry in json_data)

我也尝试使用熊猫,但也无法正确解析

import io
import json
import pandas as pd

with open('me_filename', encoding='utf-8') as f_input:
    df = pd.read_json(f_input , orient='None')

df.to_csv('output.csv', encoding='utf-8')

我需要得到的结果:

ID      Name         page   volume  url      2019-06-01 2019-07-01  2019-08-01  2019-09-01
1946592 python_1    url.com 10      url3.com    21   4    2 null
1946602 python_2    url.com 20      url1.com    5   12  10,25   null

我该怎么办?

2 个答案:

答案 0 :(得分:0)

嗯,这是一个复杂的解决方案,看起来很混乱,不再像所提供的代码,但是我相信它将解决您的问题。

首先,我对所提供的Json遇到了问题(由于第8行的结尾是','),但是设法生成了:

输出(温度csv)

ID,Name,Page,Volume,Url,2019-08-01,2019-07-01,2019-06-01,
1946592,python_1,url.com,10,url3.com,2,4,21,
1946602,python_2,url.com,20,url1.com,10.25,12,5,

使用以下内容:

import json

dates: set = set()

# Collect the data 
def get_breakdown(json):
    collected_data = []
    for result in json['results']:
        for page in json['results'][result]:
            for _id in json['results'][result][page]:
                data_struct = { 
                    'ID': _id, 
                    'Name': json['results'][result][page][_id]['keyword']['title'], 
                    'Page': page, 
                    'Volume': json['results'][result][page][_id]['keyword']['volume'], 
                    'Dates': {}
                }
                for date in dates:
                    if date in json['results'][result][page][_id]['data']:
                        data_struct['URL'] = json['results'][result][page][_id]['data'][date]['ENGINE']['DEVICE']['']['url']
                        data_struct['Dates'][date] = {'Position' : json['results'][result][page][_id]['data'][date]['ENGINE']['DEVICE']['']['position']}
                    else:
                        data_struct['Dates'][date] = {'Position' : 'null'}
                collected_data.append(data_struct)
    return collected_data

# Collect all dates across the whole data 
# structure and save them to a set
def get_dates(json):
    for result in json['results']:
        for page in json['results'][result]:
            for _id in json['results'][result][page]:
                for date in json['results'][result][page][_id]['data']:
                    dates.add(date)


# Write to .csv file
def write_csv(collected_data, file_path):
    f = open(file_path, "w")
    # CSV Title
    date_string = ''
    for date in dates:
        date_string = '{0}{1},'.format(date_string, date)
    f.write('ID,Name,Page,Volume,Url,{0}\n'.format(date_string))

    # Data
    for data in collected_data:
        position_string = ''
        for date in dates:
            position_string = '{0}{1},'.format(position_string, data['Dates'][date]['Position'])
        f.write('{0},{1},{2},{3},{4},{5}\n'.format(
            data['ID'],
            data['Name'],
            data['Page'],
            data['Volume'],
            data['URL'],
            position_string
        ))

# Code Body
with open('me_filename.json') as f_input:
    json_data = json.load(f_input)
    get_dates(json_data)
    write_csv(get_breakdown(json_data), "output.csv")

希望您可以遵循该代码,它可以完成预期的工作。我确信它可以变得更加可靠-但是,如前所述,我无法使其与您提供的基本代码一起使用。

答案 1 :(得分:0)

稍作修改后,您的代码就可以很好地工作,但是我注意到将日期显示为下一行将是格式更好的解决方案。 我试图将您的解决方案修改为这种形式,但是我在python中仍然很弱,无法轻松处理它。您还能告诉我如何实现这种csv文件格式吗?

输出(temp.csv)

ID,Name,Page,Volume,Url,data,value, 
1946592,python_1,url.com,10,url3.com,2019-08-01,2
1946592,python_1,url.com,10,url3.com,2019-07-01,4
1946592,python_1,url.com,10,url3.com,2019-06-01,21
1946602,python_2,url.com,20,url1.com,2019-08-01,10.25,
1946602,python_2,url.com,20,url1.com,2019-07-01,12,
1946602,python_2,url.com,20,url1.com,2019-06-01,5,