【问题标题】:Extracting Key from multilevel (scraped) complex structure json file in python从python中的多级(抓取)复杂结构json文件中提取密钥
【发布时间】:2021-09-17 07:37:02
【问题描述】:

我有一个多级/复杂的 json 文件 - twitter.json,我只想从这个 json 文件中提取作者 ID。

这就是我的文件“twitter.json”的外观:

[
[
    {
        "tweets_results": [
            {
                "meta": {
                    "result_count": 0
                }
            }
        ],
        "youtube_link": "www.youtube.com/channel/UCl4GlGXR0ED6AUJU1kRhRzQ"
    }
],
[
    {
        "tweets_results": [
            {
                "data": [
                    {
                        "author_id": "125959599",
                        "created_at": "2021-06-12T15:16:40.000Z",
                        "id": "1403732993269649410",
                        "in_reply_to_user_id": "125959599",
                        "lang": "pt",
                        "public_metrics": {
                            "like_count": 0,
                            "quote_count": 0,
                            "reply_count": 1,
                            "retweet_count": 0
                        },
                        "source": "Twitter for Android",
                        "text": "⌨️ Canais do YouTube:\n\n1 - Alexandre Garcia: Canal de Brasília"
                    },
                    {
                        "author_id": "521827796",
                        "created_at": "2021-06-07T20:23:08.000Z",
                        "id": "1401998177943834626",
                        "in_reply_to_user_id": "623794755",
                        "lang": "und",
                        "public_metrics": {
                            "like_count": 0,
                            "quote_count": 0,
                            "reply_count": 0,
                            "retweet_count": 0
                        },
                        "source": "TweetDeck",
                        "text": "@thelittlecouto"
                    }
                ],
                "meta": {
                    "newest_id": "1426546114115870722",
                    "oldest_id": "1367808835403063298",
                    "result_count": 7
                }
            }
        ],
        "youtube_link": "www.youtube.com/channel/UCm0yTweyAa0PwEIp0l3N_gA"
    }
]
]

我已经阅读了许多类似的 SO 问题(包括但不限于):

但是这些 json 的结构非常简单,当我尝试复制它时,我遇到了错误。

根据我的阅读,contents.tweets_results.data.author_id 是参考的方式。我正在使用contents = json.load(open("twitter.json")) 加载。任何帮助表示赞赏。

编辑:@sammywemmy 和 @balderman 的代码都对我有用。我接受了@sammywemmy,因为我使用了那个代码,但我想以某种方式归功于他们。

【问题讨论】:

    标签: python json dictionary


    【解决方案1】:

    你的数据有一个路径,你有一个嵌套在一个列表中的列表,在内部列表中,你有一个 tweets_results 键,它的值是一个字典列表;其中一个有一个data 键,其中包含一个列表/数组,其中包含一个字典,其中一个键是author_id。我们可以将路径(某种)模拟为:'[][].tweets_results[].data[].author_id'

    一种重新哈希排序:点击第一个列表,然后是内部列表,然后访问 tweets_results 键,然后访问值列表;在该值列表中,访问data 键,在与data 关联的值列表中,访问author_id

    通过这条路径,可以使用jmespath提取author_ids:

    # pip install jmespath
    import jmespath
                  # similar to re.compile
    expression = jmespath.compile('[][].tweets_results[].data[].author_id')
    expression.search(data)
    ['125959599', '521827796']
    

    如果你想从嵌套的 dicts 构建数据结构,jmespath 非常有用;但是,如果您只关心author_id 的值,则可以使用nested_lookup;它递归地搜索键并返回值:

    # pip install nested-lookup
    from nested_lookup import nested_lookup
    nested_lookup('author_id', data)
    ['125959599', '521827796']
    

    【讨论】:

    • 一个小的跟进。所以这就是我加载我的 json 的方式:with open("twitter.json"), 'r', encoding="utf8") as f: contents = json.load(f) 我应该只是nested_lookup('author_id', contents)吗?
    • 是的;请确认contents 确实是一本字典
    • 如何验证?对我来说,contents 似乎是一个列表。 (你用更详细的字典在列表中的列表中说)
    • 对不起,我的意思是列表。它应该与您共享的数据结构相匹配。您在运行 nested_lookup 时是否遇到任何问题?
    【解决方案2】:

    见下文(不涉及外部库)

    data = [
    [
        {
            "tweets_results": [
                {
                    "meta": {
                        "result_count": 0
                    }
                }
            ],
            "youtube_link": "www.youtube.com/channel/UCl4GlGXR0ED6AUJU1kRhRzQ"
        }
    ],
    [
        {
            "tweets_results": [
                {
                    "data": [
                        {
                            "author_id": "125959599",
                            "created_at": "2021-06-12T15:16:40.000Z",
                            "id": "1403732993269649410",
                            "in_reply_to_user_id": "125959599",
                            "lang": "pt",
                            "public_metrics": {
                                "like_count": 0,
                                "quote_count": 0,
                                "reply_count": 1,
                                "retweet_count": 0
                            },
                            "source": "Twitter for Android",
                            "text": "⌨️ Canais do YouTube:\n\n1 - Alexandre Garcia: Canal de Brasília"
                        },
                        {
                            "author_id": "521827796",
                            "created_at": "2021-06-07T20:23:08.000Z",
                            "id": "1401998177943834626",
                            "in_reply_to_user_id": "623794755",
                            "lang": "und",
                            "public_metrics": {
                                "like_count": 0,
                                "quote_count": 0,
                                "reply_count": 0,
                                "retweet_count": 0
                            },
                            "source": "TweetDeck",
                            "text": "@thelittlecouto"
                        }
                    ],
                    "meta": {
                        "newest_id": "1426546114115870722",
                        "oldest_id": "1367808835403063298",
                        "result_count": 7
                    }
                }
            ],
            "youtube_link": "www.youtube.com/channel/UCm0yTweyAa0PwEIp0l3N_gA"
        }
    ]
    ]
    
    ids = []
    for entry in data:
      for sub in entry:
       result = sub['tweets_results']
       if result[0].get('data'):
        info = result[0]['data']
        for item in info:
          ids.append(item.get('author_id','not_found'))
    print(ids)
    

    输出

    ['125959599', '521827796']
    

    【讨论】:

    • 问题 - 我有一个文件,而不是一个字符串。因此,当您执行data = [...] 时,您会将它们作为字符串输入。我正在做一个content = json.load(file)
    • @Nilima - 你所做的是正确的,将导致所需的输出。试试看。就做data = json.load(file)
    猜你喜欢
    • 2021-09-19
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多