代码之家  ›  专栏  ›  技术社区  ›  RustyShackleford

无论字典中是否缺少值,如何将JSON字典对象爬网到数据帧中?

  •  1
  • RustyShackleford  · 技术社区  · 6 年前

    import requests 
    import jmespath
    import pandas as pd
    import json
    
    url = 'a.com'
    
    r = requests.get(url).json()
    

    {'question': [{
       'response': {'firstname': {'value': 'John'},
        'lastname': {'value': 'Bob'}},
       'profile_question': [{
         'identities': [{'type': 'ID,
           'value': '1'},
          {'type': 'EMAIL',
           'value': 'test@test.com'}]}]}]}
    

    我尝试将其放入json.fr中,但得到的错误是它的格式不正确。我如何能够按原样抓取该对象,但不能成功地满足我的需要。

    jmespath 图书馆要爬行,要拉出四条信息 firstname, lastname, ID, EMAIL

        lst =[]
    
        fname = jmespath.search('question[*].response.{firstname:firstname.value}',my_dict)
        lst.append(fname)
    
        lname = jmespath.search('question[*].response.{lastname:lastname.value}',my_dict)
        lst.append(lname)
    
        email_path = jmespath.search("question[*].profile_question[].identities.{email:[?type=='EMAIL'].value}",my_dict)
        lst.append(email)
    
        ID = jmespath.search("question[*].profile_question[].identities.{email:[?type=='ID'].value}",my_dict)
        lst.append(ID)
    

    我将其添加到一个列表中,希望每次迭代都能创建元组,并将其推送到数据帧中。

    列表如下所示:

    [[{'firstname': 'John'}],
     [{'lastname': 'Bob'}],
     [{'email': ['test@test.com']}],
     [{'ID': ['1']}]]
    

    {'question': [{
       'response': {'firstname': {'value': 'John'},
        'lastname': {'value': 'Bob'}},
       'profile-question': [{
         'identities': [{'type': 'ID,
           'value': '1'},
          {'type': 'EMAIL',
           'value': 'test@test.com'}]}]}],
       'response': {'firstname': {'value': 'John1'},
        'lastname': {'value': 'Bob1'}},
       'profile-question': [{
         'identities': [{'type': 'ID,
           'value': '2'}]}]}
    

    导致我的列表的行为如下(我不知道为什么):

    [[{'firstname': 'John'}], [{'email': ['test@test.com']}], [{'email': ['1']},[{'firstname': 'John'}],
     [{'lastname': 'Bob'}],
     [{'email': [][][]}],
     [{'ID': ['1']}]]]
    

    firstname         lastname      email                ID
    john                 bob        test@test.com        1 
    john1                bob1       test@test.com        1
    

    firstname, lastname, email, ID 然后像这样附加到数据帧中

    firstname         lastname      email                    ID
        john                 bob        test@test.com        1 
        john1                bob1                            2
    

    jmespath 库,并且要补充的是,上面的字典有更多的字段,我已经缩短了,所以只列出了关键点和它们的缩进。

    1 回复  |  直到 6 年前
        1
  •  1
  •   SafeDev    6 年前

    首先,错误的原因是json对象在ID后面缺少引号。

     {'question': [{
       'response': {'firstname': {'value': 'John'},
        'lastname': {'value': 'Bob'}},
       'profile_question': [{
         'identities': [{'type': 'ID,
           'value': '1'},
          {'type': 'EMAIL',
           'value': 'test@test.com'}]}]}]}
    

    应该是这样的:

    {'question': [{
       'response': {'firstname': {'value': 'John'},
        'lastname': {'value': 'Bob'}},
       'profile_question': [{
         'identities': [{'type': 'ID',
           'value': '1'},
          {'type': 'EMAIL',
           'value': 'test@test.com'}]}]}]}
    

    从这里,您可以使用json库将json对象转换为具有 json.loads()

    import jmespath as jp
    import pandas as pd
    
    
    jon = {'question':
                  [{'response': {'firstname': {'value': 'John'},
                                 'lastname': {'value': 'Bob'}},
                    'profile_question': [{'identities': [{'type': 'ID',
                                                          'value': '1'},
                                                         {'type': 'EMAIL', 'value': 'test@test.com'}]}]}]}
    
    
    jsons = [jon] # list of all json objects
    df_list = []
    for json in jsons:
        try:
            fname = jp.search('question[*].response.firstname.value', jon)[0]
        except IndexError:
            fname = None
        try:
            lname = jp.search('question[*].response.lastname.value', jon)[0]
        except IndexError:
            lname = None
        try:
            email = jp.search("question[*].profile_question[].identities.{email:[?type=='EMAIL'].value}", jon)[0]['email'][0]
        except IndexError:
            email = None
        try:
            user_id = jp.search("question[*].profile_question[].identities.{email:[?type=='ID'].value}", jon)[0]['email'][0]
        except IndexError:
            user_id = None
        df_list.append(pd.DataFrame({'firstname': fname, 'lastname': lname, 'email': email, 'id': user_id}, index=[0]))
    
    
    df = pd.concat(df_list, ignore_index=True, sort=False)
    print(df)
    
    推荐文章