我将如何在Perl中读取此数据结构?具有包含列表的键的字典/哈希。Python::内联给我错误

我将如何在Perl中读取此数据结构?具有包含列表的键的字典/哈希。Python::内联给我错误,python,list,perl,hash,inline,Python,List,Perl,Hash,Inline,我已经为这个简单的问题挣扎了大约3周。我不明白为什么,我愿意付出一切来解决这个问题,哈哈 我试图从下面的数据结构中读取值。文档称这是一本字典,其键包含该类型结果的列表 示例:我使用eval函数获得主查询回复。我查找“song_hits”键以获得该结构。然后我查找键“track”并解析它。问题是如何进入“轨道”部分 当我按照Perl文档告诉我的方式进行操作时,我无法通过包“Inline::Python::object::Data”找到对象方法“FIRSTKEY” 因此,我想知道是否有一种方法可以使

我已经为这个简单的问题挣扎了大约3周。我不明白为什么,我愿意付出一切来解决这个问题,哈哈

我试图从下面的数据结构中读取值。文档称这是一本字典,其键包含该类型结果的列表

示例:我使用eval函数获得主查询回复。我查找“song_hits”键以获得该结构。然后我查找键“track”并解析它。问题是如何进入“轨道”部分

当我按照Perl文档告诉我的方式进行操作时,我无法通过包“Inline::Python::object::Data”找到对象方法“FIRSTKEY”

因此,我想知道是否有一种方法可以使用eval函数来读取值,从而绕过ObjectData的哈希键限制,如果我知道确切的键,是否有另一种方法来读取值,或者我只是在做完全错误的事情

{
'album_hits': [
{
    'album':
    {
        'albumArtRef': 'http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fF...',
        'albumArtist': 'J.Cole',
        'albumId': 'Bfp2tuhynyqppnp6zennhmf6w3y',
        'artist': 'J.Cole',
        'artistId': ['Ajgnxme45wcqqv44vykrleifpji'],
        'description_attribution':
        {
            'kind': 'sj#attribution',
            'license_title': 'Creative Commons Attribution CC-BY',
            'license_url': 'http://creativecommons.org/licenses/by/4.0/legalcode',
            'source_title': 'Freebase',
            'source_url': ''
        },
        'explicitType': '1',
        'kind': 'sj#album',
        'name': 'Work Out',
        'year': 2011
    },
    'type': '3'
}],
'artist_hits': [
{
    'artist':
    {
        'artistArtRef': 'http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlm...',
        'artistArtRefs': [
        {
            'aspectRatio': '2',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlmKX3x_K...'
        }],
        'artistId': 'Ajgnxme45wcqqv44vykrleifpji',
        'artist_bio_attribution':
        {
            'kind': 'sj#attribution',
            'source_title': 'David Jeffries, Rovi'
        },
        'kind': 'sj#artist',
        'name': 'J. Cole'
    },
    'type': '2'
}],
'playlist_hits': [
{
    'playlist':
    {
        'albumArtRef': [
        {
            'url': 'http://lh3.googleusercontent.com/KJsAhrg8Jk_5A4xYLA68LFC...'
        }],
        'description': 'Workout Plan ',
        'kind': 'sj#playlist',
        'name': 'Workout',
        'ownerName': 'Ida Sarver',
        'shareToken': 'AMaBXyktyF6Yy_G-8wQy8Rru0tkueIbIFblt2h0BpkvTzHDz-fFj6P...',
        'type': 'SHARED'
    },
    'type': '4'
}],
'situation_hits': [
{
    'situation':
    {
        'description': 'Level up and enter beast mode with some loud, aggressive music.',
        'id': 'Nrklpcyfewwrmodvtds5qlfp5ve',
        'imageUrl': 'http://lh3.googleusercontent.com/Cd8WRMaG_pDwjTC_dSPIIuf...',
        'title': 'Entering Beast Mode',
        'wideImageUrl': 'http://lh3.googleusercontent.com/8A9S-nTb5pfJLcpS8P...'
    },
    'type': '7'
}],
'song_hits': [
{
    'track':
    {
        'album': 'Work Out',
        'albumArtRef': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fFdxj5w...'
        }],
        'albumArtist': 'J.Cole',
        'albumAvailableForPurchase': True,
        'albumId': 'Bfp2tuhynyqppnp6zennhmf6w3y',
        'artist': 'J Cole',
        'artistId': ['Ajgnxme45wcqqv44vykrleifpji', 'Ampniqsqcwxk7btbgh5ycujij5i'],
        'composer': '',
        'discNumber': 1,
        'durationMillis': '234000',
        'estimatedSize': '9368582',
        'explicitType': '1',
        'genre': 'Pop',
        'kind': 'sj#track',
        'nid': 'Tq3nsmzeumhilpegkimjcnbr6aq',
        'primaryVideo':
        {
            'id': '6PN78PS_QsM',
            'kind': 'sj#video',
            'thumbnails': [
            {
                'height': 180,
                'url': 'https://i.ytimg.com/vi/6PN78PS_QsM/mqdefault.jpg',
                'width': 320
            }]
        },
        'storeId': 'Tq3nsmzeumhilpegkimjcnbr6aq',
        'title': 'Work Out',
        'trackAvailableForPurchase': True,
        'trackAvailableForSubscription': True,
        'trackNumber': 1,
        'trackType': '7',
        'year': 2011
    },
    'type': '1'
}],
'station_hits': [
{
    'station':
    {
        'compositeArtRefs': [
        {
            'aspectRatio': '1',
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/3aD9mFppy6PwjADnjwv_w...'
        }],
        'contentTypes': ['1'],
        'description': 'These riff-tastic metal tracks are perfect for getting the blood pumping.',
        'imageUrls': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh5.ggpht.com/YNGkFdrtk43e8H941fuAHjflrNZ1CJUeqdoys...'
        }],
        'kind': 'sj#radioStation',
        'name': 'Heavy Metal Workout',
        'seed':
        {
            'curatedStationId': 'Lcwg73w3bd64hsrgarnorif52r',
            'kind': 'sj#radioSeed',
            'seedType': '9'
        },
        'skipEventHistory': [],
        'stationSeeds': [
        {
            'curatedStationId': 'Lcwg73w3bd64hsrgarnorif52r',
            'kind': 'sj#radioSeed',
            'seedType': '9'
        }]
    },
    'type': '6'
}],
'video_hits': [
{
    'score': 629.6226806640625,
    'type': '8',
    'youtube_video':
    {
        'id': '6PN78PS_QsM',
        'kind': 'sj#video',
        'thumbnails': [
        {
            'height': 180,
            'url': 'https://i.ytimg.com/vi/6PN78PS_QsM/mqdefault.jpg',
            'width': 320
        }],
        'title': 'J. Cole - Work Out'
    }
}]
}

经过3周的不同尝试,代码已被清理,但已被破坏:(我已尝试了for、foreach、while,但它最多只能读取整个unicode数组、错误或空字符串)

我尝试了阅读,但出现了很多错误,包括:

  • “密钥”不存在
  • 在使用严格引用时,不能将字符串(“跟踪”)用作哈希引用
  • 引用上键的参数类型必须为未lessed hashref或arrayref
我的完整测试文件: GoogleApi-PM(Python-GAPI-Hook):

编辑:信息,有几个人想要修复未维护的旧代码,所以我提供了帮助,并让除此之外的所有东西都正常工作

旧代码Git:


我使用的Google Api Python:

好的,这不是一个真正的答案,但出于我的善意,我为您清理了您的数据。这是一个真正的Python dict。我不知道一些数字字符串值是否应该是int,所以我没有弄乱它们。由您决定如何处理被截断的URL

另一种方法是将
True
更改为
True
False
更改为
False
,并将dict解析为JSON

{
“专辑热门歌曲”:[
{
“相册”:
{
'albumArtRef':'http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fF...',
“专辑艺术家”:“J.Cole”,
'albumId':'Bfp2tuhynyqppnp6zennhmf6w3y',
‘艺术家’:‘J·科尔’,
“artistId”:[ajgnxme45wcqv44vykreifpji'],
“描述和属性”:
{
“种类”:“sj#归属”,
“许可证名称”:“知识共享署名抄送人”,
“许可证url”:http://creativecommons.org/licenses/by/4.0/legalcode',
'来源_标题':'自由基',
“源url:”“
},
“explicitType”:“1”,
“种类”:“sj专辑”,
'姓名':'锻炼',
“年份”:2011年
},
“类型”:“3”
}],
“艺术家之歌”:[
{
“艺术家”:
{
“artistArtRef”:http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlm...',
《星际迷航记》:[
{
“aspectRatio”:“2”,
“自动生成”:错误,
“种类”:“sj#imageRef”,
“url”:”http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlmKX3x_K...'
}],
“artistId”:“AJGNXME45WCQV44VYKRLEIFPJI”,
“艺术家的归属”:
{
“种类”:“sj#归属”,
“资料来源:Rovi的David Jeffries”
},
“种类”:“sj#艺术家”,
“姓名”:“J.科尔”
},
“类型”:“2”
}],
“播放列表\u点击次数”:[
{
“播放列表”:
{
“albumArtRef”:[
{
“url”:”http://lh3.googleusercontent.com/KJsAhrg8Jk_5A4xYLA68LFC...'
}],
“说明”:“训练计划”,
“种类”:“sj#播放列表”,
'姓名':'训练',
“ownerName”:“Ida Sarver”,
“shareToken”:“AMaBXyktyF6Yy_G-8wqy8rru0tkueibibblt2h0bpkvtzhdz-fFj6P…”,
“类型”:“共享”
},
“类型”:“4”
}],
"情况":[
{
“情况”:
{
“描述”:“升级并进入野兽模式,播放一些响亮、咄咄逼人的音乐。”,
“id”:“nrklpcyfewrmodvdtds5qlfp5ve”,
“imageUrl”:”http://lh3.googleusercontent.com/Cd8WRMaG_pDwjTC_dSPIIuf...',
“标题”:“进入野兽模式”,
“wideImageUrl”:”http://lh3.googleusercontent.com/8A9S-nTb5pfJLcpS8P...'
},
“类型”:“7”
}],
“宋_热门歌曲”:[
{
“轨道”:
{
“相册”:“锻炼”,
“albumArtRef”:[
{
“aspectRatio”:“1”,
“自动生成”:错误,
“种类”:“sj#imageRef”,
“url”:”http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fFdxj5w...'
}],
“专辑艺术家”:“J.Cole”,
“albumAvailableForPurchase”:True,
'albumId':'Bfp2tuhynyqppnp6zennhmf6w3y',
“艺术家”:“J科尔”,
“artistId:[“AJGNXME45WCQV44VYKRLEIFpJI”,“AMPNIQSQQCWxK7BTBGH5YCUJIJ5I”],
“作曲家”:“,
“discNumber”:1,
“durationMillis”:“234000”,
“estimatedSize”:“9368582”,
“explicitType”:“1”,
“流派”:“流行”,
“种类”:“sj#track”,
“nid”:“TQ3NSMZEUMHILLPEGKIMJCNBR6AQ”,
“primaryVideo”:
{
“id”:“6PN78PSQSM”,
“种类”:“sj#video”,
“缩略图”:[
{
‘高度’:180,
“url”:”https://i.ytimg.com/vi/6PN78PS_QsM/mqdefault.jpg',
“宽度”:320
}]
},
'storeId':'Tq3nsmzeumhil
sub search {
    my $query = shift;

    my $uri = 'googlemusic:search:' . $query;

    if (my $result = $cache->get($uri)) {
        return $result;
    }

    my $googleResult;
    my $result = {
        tracks => [],
        albums => [],
        artists => [],
    };        

    eval {
        $googleResult = $googleapi->search($query, $prefs->get('max_search_items'));
    };
    if ($@) {
        $log->error("Not able to search All Access for \"$query\": $@");
        return;
    }
    #gives not an ARRAY refernce error
    for my $hit (@{$googleResult->{song_hits}}) {
        push @{$result->{tracks}}, to_slim_track($hit->{track});
    }
    #works, but gives an error on the next line, 'newlist' object has no attribute 'album' 
    for my $hit ({$googleResult->{album_hits}}) {
        push @{$result->{albums}}, album_to_slim_album($hit->{album});
    }
    #Perl and others recommended way, but gives  Can't locate object method "FIRSTKEY" via package "Inline::Python::Object::Data"
    for my $hit (%{$googleResult->{artist_hits}}) {
        push @{$result->{artists}}, artist_to_slim_artist($hit->{artist});
    }

    # Add to the cache
    $cache->set($uri, $result, $CACHE_TIME);

    return $result;
}
# Other code from the question ...
use JSON::XS;

# For tests I loaded shown data into $googleResult (did not run this eval)
eval {
    $googleResult = $googleapi->search($query, $prefs->get('max_search_items'));
};
if ($@) {
    $log->error("Not able to search All Access for \"$query\": $@");
    return;
}

# The structure shown in the question needs a cleanup
# But this may be a road to madness, if there is more
$googleResult =~ s/'/"/g;        # ' turn off wrong editor coloring
$googleResult =~ s/False/false/g;
$googleResult =~ s/True/true/g;

my $coder = JSON::XS->new;    
# There are many options for how to set it up. Example:
# JSON::XS->new->ascii->pretty->allow_nonref;    

my $data = $coder->decode($googleResult);  
# Now this is a normal Perl data structure that we can work with. 
# Look at what's under 'album_hits' for example
my $ralbhits = $data->{'album_hits'};  
print Dumper($ralbhits);
# We get: VAR1 = [ { 'album' => { albumID => ... } } ]
# Array reference, with nested hash references as the sole element

# Extract the 'artist'
my $artist = $ralbhits->[0]->{'album'}->{'artist'};
print "$artist\n";
# Get the hashref for album
my $ralbum = $ralbhits->[0]->{'album'};
my $artist = $ralbum->{'artist'};
$googleResult =~ s/False/false/g;
$googleResult =~ s/True/true/g;
$googleResult =~ s/u"/"/g;
# There are also escaped characters in text, escape that backslash
$googleResult =~ s|(\\)|$1$1|g;
# Correct delimiters from u'...' to "...", see text below   
$googleResult =~ s/u'(.*?)' (?= []:},] )/"$1"/gx;
# We are good now, decode it
my $data = $coder->decode($googleResult); 
my $alb = $data->[0]{track}{album};
print "$alb\n";
use Inline::Python qw(py_eval);

my $song_hits = py_eval("[x for x in $googleResult->{song_hits}]", 0);
for my $hit (@$song_hits) {
    push @{$result->{tracks}}, to_slim_track($hit->{track});
}