如何检索与编号最高的JSON时间戳关联的元数据?

时间:2019-04-14 17:51:42

标签: php json bash

我正在尝试为外部应用程序解析JSON格式的元数据。但是,我只需要最后播放的歌曲的元数据,而我要处理的JSON就有10或15首歌曲。

wklh.sh:

#!/bin/sh
curl -v --silent http://player.listenlive.co/41851/en/songhistory >/var/tmp/wklh$1.a.txt
pta=`cat /var/tmp/wklh$1.a.txt | grep songs > /var/tmp/wklh$1.b.txt`
ptb=`cat /var/tmp/wklh$1.b.txt | sed -n -e '/var songs = /,/; <span title/ p' > /var/tmp/wklh$1.c.txt`
ptc=`cat /var/tmp/wklh$1.c.txt | grep songs > /var/tmp/wklh$1.d.txt`
ptd=`cat /var/tmp/wklh$1.d.txt | sed -i 's/var songs = \[//g' /var/tmp/wklh$1.d.txt`
ptd=`cat /var/tmp/wklh$1.d.txt | sed -i 's/<ol class="songs tracks"><\/ol>//g' /var/tmp/wklh$1.d.txt`
ptd=`cat /var/tmp/wklh$1.d.txt | sed -i 's/\]//g' /var/tmp/wklh$1.d.txt`
ptd=`cat /var/tmp/wklh$1.d.txt | sed -i 's/;//g' /var/tmp/wklh$1.d.txt`

json=`cat /var/tmp/wklh$1.d.txt`
echo $json

metadata=`php /etc/asterisk/scripts/music/wklh.php $json`
echo $metadata

我意识到这不是很有效,但是某些sed语句不能完全起作用,因此我不得不将它们分开。

wklh.sh:

<?php
$md=json_decode($argv[1]);
$title=$md->title;
$artist=$md->artist;
$album=$md->album;
echo "$title*$artist*$album";
?>

这与另一个PHP文件writ.php几乎相同,我用来解析类似的JSON(https://us.api.iheart.com/api/v3/live-meta/stream/2689/currentTrackMeta

writ.php解析:

{"artistId":893,"albumId":58817688,"trackId":58817690,"title":"Cum on Feel the Noize","artist":"Quiet Riot","album":"Metal Health","trackDuration":287,"imagePath":"http://image.iheart.com/ihr-ingestion-pipeline-production-sbmg/A10301A0001103372T_20180629201531958/4476232.20126.jpg","explicitLyrics":false,"lyricsId":0,"startTime":1555263475000,"endTime":1555263681000,"playbackRights":{"onDemand":true},"dataSource":"Pnp"}

这是writ.php:

<?php
$url = "https://us.api.iheart.com/api/v3/live-meta/stream/2689/currentTrackMeta";
$contents = file_get_contents($url);
$md = json_decode($contents);
$title = $md->title;
$artist = $md->artist;
$album = $md->album;
echo "$title*$artist*$album";
?>

wklh.sh将以下内容发送到wklh.php:

{"timestamp":1555254209000,"title":"Back On The Chain Gang","trackId":"5f_6e4abbe7-c71b-48c0-8412-7b471e514164","artist":"The Pretenders","artistId":"a0_e9c832b0-384b-4ee6-aec0-111372784aac","album":"The Singles","albumId":"9f_ca6cda27-1fe7-4264-9ba7-acbc6ccf658b","npe_id":"9242bddc7ab5d1560103303a30f581072a"},{"timestamp":1555254438000,"title":"Blowin' Free","trackId":"a5_fefb9583-8401-442e-8fe1-743f259ca8a2","artist":"Wishbone Ash","artistId":"8e_406f1b42-0c9e-4427-aeb7-02f78e188ec4","album":"Argus","albumId":"b9_40b81523-e997-489e-b007-b91381eadf2a","npe_id":"899578f2074ccbe100241441e85adf04e1"},{"timestamp":1555255800000,"title":"Eighteen","trackId":"5c_e7a1326d-be32-4f64-8feb-e8292277724c","artist":"Alice Cooper","artistId":"a5_ee58c59f-8e7f-4430-b8ca-236c4d3745ae","album":"School's Out and Other Hits","albumId":"34_5a7df40f-0d84-40e6-84b1-71c6cef5224d","npe_id":"e3fcf5b90e463320383bbf84050653c63e"},{"timestamp":1555260315000,"title":"Breakfast in America","trackId":"5b_da4b050d-a32a-4159-aee9-77e1fc7f3e13","artist":"Supertramp","artistId":"bf_d2ff6b6b-fc30-48dc-8952-06f9d8fc64f8","album":"Breakfast In America","albumId":"47_d779ab27-4095-4ad9-9663-d4ffd567aa4e","npe_id":"eee7f84d2b6879bc782151c3a516afd916"},{"timestamp":1555261272000,"title":"Spirit of Radio","trackId":"3c_63802349-97dd-4967-9bba-2ea2213262cb","artist":"Rush","artistId":"e5_eb62559f-2fb2-4879-af18-a23ea2ee91b1","album":"The Best Symfo Rock","albumId":"ba_5f3d58e6-e3ca-410b-80ea-317f4cd1afe9","npe_id":"4fd76d35647d3eb645be92b3679b77d64d"},{"timestamp":1555261568000,"title":"Beast of Burden","trackId":"09_55956d3e-c5d4-4332-a377-bf77c463656e","artist":"The Rolling Stones","artistId":"1b_b071f9fa-14b0-4217-8e97-eb41da73f598","album":"Some Girls","albumId":"95_635239b4-986a-4cb7-90ba-bf213d5c9f78","npe_id":"f0b17c7012050705702a2e93fd1976288c"},{"timestamp":1555261829000,"title":"For Those About to Rock (We Salute You)","trackId":"d1_3ee8a730-413d-4f8e-b1c0-bd2694a65aa4","artist":"AC\/DC","artistId":"b6_66c662b6-6e2f-4930-8610-912e24c63ed1","album":"Who Made Who","albumId":"af_8de9dab6-6ff5-4a3e-b191-00ec7e974ef8","npe_id":"55c6ddd902781b70d28dc724cda5e9f325"},{"timestamp":1555262568000,"title":"Foreplay \/ Long Time","trackId":"21_b841b5f6-b968-4e83-8991-f1665ae96784","artist":"Boston","artistId":"f8_0d8b0d50-e4cf-4da4-965d-f24c58ec3268","album":"Boston","albumId":"b3_5c70a6a9-43ab-448d-a53e-0c7e933a6856","npe_id":"694f76ee4d7c2474b36b6984be7ee8e590"},{"timestamp":1555263036000,"title":"Scar Tissue","trackId":"de_3ec5cb52-7dde-4d11-aec2-1c1af8fc559c","artist":"Red Hot Chili Peppers","artistId":"c8_8bfac288-ccc5-448d-9573-c33ea2aa5c30","album":"Greatest Hits","albumId":"fc_b95d3a86-6640-4a02-850a-2b842ad601d3","npe_id":"815bf692959cd3f61f3f274e5e2085841c"},{"timestamp":1555263252000,"title":"Take It Easy","trackId":"d7_d5abb4ca-8cd5-468a-bdbc-53f3223bb9be","artist":"Eagles","artistId":"5e_f46bd570-5768-462e-b84c-c7c993bbf47e","album":"The Very Best of the Eagles","albumId":"34_9c6af437-a471-4bcd-9442-e5b9d9b9d064","npe_id":"58658057287a5ed71751f1983a8b00387d"}
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 3
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 4
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 5

wklh.php接收到的JSON与writ.php接收到的JSON类似,只是一个返回1首歌曲的元数据,而我的脚本返回最后10或15首歌曲的元数据。我只对最近播放过的歌曲的相同三个领域感兴趣。我该如何解析JSON(最后一个(编号最高的)时间戳),然后仅返回该歌曲的花括号(包括花括号)之间的内容?

我确定可以使用PHP选择所需的JSON子集后,我的wklh.sh/writ.php脚本组合应该可以正常工作。之后,PHP代码类似于我用于writ.php的代码,我可以使用它。我可以对我的PHP脚本进行修改以完成此操作吗?

谢谢!

**更新**

在答案中使用脚本时返回的代码:

{ "timestamp": 1555267001000, "title": "Foolin'", "trackId": "f6_a3e1ef19-9120-410c-b1fe-1a2609145e52", "artist": "Def Leppard", "artistId": "c1_7249b899-8db8-43e7-9e6e-22f1e736024e", "album": "Pyromania", "albumId": "5a_77797bc1-738f-357c-8c5a-233042906849", "npe_id": "0dfb9d624a4f118d2ffe9ec621c5fdc9cc" }
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 3
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 4
PHP Notice:  Trying to get property of non-object in /etc/asterisk/scripts/music/wklh.php on line 5

这是我再次使用的php:

<?php
$md=json_decode($argv[1]);
$title=$md->title;
$artist=$md->artist;
$album=$md->album;
echo "$title*$artist*$album";
?>

如果我直接运行php脚本:

/etc/asterisk/scripts/music/wklh.php: line 1: ?php: No such file or directory
/etc/asterisk/scripts/music/wklh.php: line 2: syntax error near unexpected token `$argv[1]'
/etc/asterisk/scripts/music/wklh.php: line 2: `$md=json_decode($argv[1]);'

4 个答案:

答案 0 :(得分:1)

由于您在最后一条评论中询问了一个命令,因此这里以一行(可能是改进的)方式以bash的形式获得了最后一首歌曲(需要jq):

curl -v --silent http://player.listenlive.co/41851/en/songhistory |
sed -nr 's/^.*\s*var songs\s*=\s*(\[[^]]+\]).*$/\1/p' |
jq -r '.[length-1]'

但是,此代码假定一切都按预期进行(HTML输出未更改,已检索,其中包含有效的JSON等。

答案 1 :(得分:1)

似乎分配给var songs的json是一行。

如果是这样,则可以通过以下方式将其提取:

curl -v --silent http://player.listenlive.co/41851/en/songhistory |\
sed '
    / var songs = /!d;  # ignore anything except the assignment
    s/^[^[]*//;         # strip prefix
    s/[^]]*$//;         # strip suffix
    q;                  # quit as nothing else should match
'

然后可以将其传送到jq中以进行进一步处理。

如果我们假设没有嵌套的{},则可以直接提取最终元素:

curl -v --silent http://player.listenlive.co/41851/en/songhistory |\
sed '
    / var songs = /!d;
    s/^.*{/{/;
    s/}.*$/}/;
    q;
'

答案 2 :(得分:1)

@Amessihel的答案很酷,但这是不使用phpjq的答案。您的目标似乎是为最近播放的歌曲打印 title * artist * album 。幸运的是,最近播放的歌曲出现在列表的最后,因此我们只需要提取json数组的最后一个元素。

curl -s http://player.listenlive.co/41851/en/songhistory |
  grep -o '\[{"timestamp":.*\]' |
  sed 's/},{/\n/g' |
  tail -n1 |
  sed 's/.*"title":"\([^"]\+\)".*"artist":"\([^"]\+\)".*"album":"\([^"]\+\)".*/\1*\2*\3/'

PS:您也可以使用jq并跳过php

curl -s http://player.listenlive.co/41851/en/songhistory |
  grep -o '\[{"timestamp":.*\]' |
  jq '.[length-1] | .title,.artist,.album' |
  tr '\n' '*'

答案 3 :(得分:1)

不需要curlsedjqXidel,HTML / XML / JSON解析器(使用CSS,XPath,XQuery,JSONiq和模式模板)可以自行完成所有操作。

打开网址,提取并解析以var songs =开头的json:

xidel -s http://player.listenlive.co/41851/en/songhistory -e '
  json(
    //script/extract(
      .,
      "var songs = (.+);",
      1
    )[.]
  )
'
[
  {
    "timestamp": 1555445370000,
    "title": "Fortunate Son",
    "trackId": "4a_26b57ded-d5bd-42f8-a440-d8fd5b48c6c2",
    "artist": "Creedence Clearwater Revival",
    "artistId": "1d_44c48a1b-defd-4222-bee6-03f9ee9a7be9",
    "album": "Platinum",
    "albumId": "07_9b0f8fc8-65d8-4321-9699-57ce36e192d0",
    "npe_id": "514295ba2099e4deaca9291d1affa49a43"
  },
  [...]
  {
    "timestamp": 1555448565000,
    "title": "Lunatic Fringe",
    "trackId": "35_725d3938-1ddb-43b7-b6a3-5a8be7a23dee",
    "artist": "Red Rider",
    "artistId": "14_a22d8a5d-1ca1-43cf-85a6-07f64a18273d",
    "album": "As Far As Siam",
    "albumId": "86_e1d05a59-4817-43e9-a315-09e953035b19",
    "npe_id": "8834a1fecc4f06783f155494497a1c7110"
  }
]

返回数组的最后一个对象:

xidel -s http://player.listenlive.co/41851/en/songhistory -e '
  json(
    //script/extract(
      .,
      "var songs = (.+);",
      1
    )[.]
  )()[last()]
'
{
  "timestamp": 1555448565000,
  "title": "Lunatic Fringe",
  "trackId": "35_725d3938-1ddb-43b7-b6a3-5a8be7a23dee",
  "artist": "Red Rider",
  "artistId": "14_a22d8a5d-1ca1-43cf-85a6-07f64a18273d",
  "album": "As Far As Siam",
  "albumId": "86_e1d05a59-4817-43e9-a315-09e953035b19",
  "npe_id": "8834a1fecc4f06783f155494497a1c7110"
}

字符串连接标题,艺术家和专辑:

xidel -s http://player.listenlive.co/41851/en/songhistory -e '
  json(
    //script/extract(
      .,
      "var songs = (.+);",
      1
    )[.]
  )()[last()]/join(
    (
      title,
      artist,
      album
    ),
    "*"
  )
'
Lunatic Fringe*Red Rider*As Far As Siam

单线:

xidel -s http://player.listenlive.co/41851/en/songhistory -e 'json(//script/extract(.,"var songs = (.+);",1)[.])()[last()]/join((title,artist,album),"*")'