使用 Java / Spring Boot 从 YouTube 数据 API 中提取数据
Extract data from YouTube Data API with Java / Sprint Boot
我正在尝试提取使用 YT 数据 API 获得的所有视频的标题、videoId 和描述数据。我能够在 Postman 和 Chrome 浏览器中 return 看起来像 JSON 格式的数据(但当我使用 getClass()
检查时它实际上是 LinkedHashMap),但是无法从我上面提到的特定键中提取值。
我试过了:
System.out.println((rest.getForObject(url, Object.class, params)).get("items"));
它要求我转换为 JSONObject
总的来说,我需要提取数据并将其转换为 xml,然后再将其发送到 ActiveMQ
编辑:
我在 Postman/Chrome 浏览器
中获取的格式
{
"kind": "youtube#searchListResponse",
"etag": "3LV4enCWAzOaiqJb_cMIUVklXJY",
"nextPageToken": "CAUQAA",
"regionCode": "CA",
"pageInfo": {
"totalResults": 478712,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "gt6x7J2XpzU8Mpb3yv9_HmNTzWY",
"id": {
"kind": "youtube#video",
"videoId": "I_ZK0t9-llo"
},
"snippet": {
"publishedAt": "2021-03-01T18:15:13Z",
"channelId": "UC2WHjPDvbE6O328n17ZGcfg",
"title": "Stack Overflow is full of idiots.",
"description": "The Stack Overflow culture needs to be fixed. The overall gatekeeping & elitism in computer science & programming - as a whole ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "ForrestKnight",
"liveBroadcastContent": "none",
"publishTime": "2021-03-01T18:15:13Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "RwmGP1qMzUCzK6oV82s0NUEOETw",
"id": {
"kind": "youtube#video",
"videoId": "sMIslcynm0Q"
},
"snippet": {
"publishedAt": "2021-03-07T16:00:13Z",
"channelId": "UCXwjZTvpFiBl93ACCUh1NXQ",
"title": "How To Use Stack Overflow (no, ForrestKnight, it's not full of idiots)",
"description": "Hey everyone, I can't believe I have to make this video. Unfortunately ForrestKnight recently made a video saying Stack Overflow ...",
"thumbnails": {
...
Edit2:我试过了
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
JSONArray array = jsonObject.getJSONArray("items" );
for(int i=0;i<array.length();i++){
JSONObject snippet =array.getJSONObject(i);
System.out.println(snippet.getJSONObject("snippet").get("title"));
}
JSONObject["items"] not found.
编辑3:
我也试过没有 Edit2 和只是
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
System.out.println(jsonObject);
没有错误,我正要获取 Postman 中显示的数据。但是在控制台中打印 {}
,这意味着我可能没有获得数据并且无法提取。
我尝试使用 .get 提取 System.out.println(jsonObject.get("items"));
我得到了同样的错误 JSONObject["items"] not found.
似乎可能是格式错误,它看起来又像 json 了,为了使用 .get,我把它放在 jsonObject 中,但什么也没找到
Edit4:我可以使用
确认我得到的数据是Json(就像文档上说的那样)
try {
new JSONObject(rest.getForObject(url, Object.class, params));
} catch (JSONException ex) {
// edited, to include @Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(rest.getForObject(url, Object.class, params));
} catch (JSONException ex1) {
return false;
}
}
return true;
返回真值
Edit5:尝试后似乎键为空
String[] keys = JSONObject.getNames(jsonObject);
// iterate over them
for (String key1 : keys) {
// retrieve the values
Object value = jsonObject.get(key1);
// if you just have strings:
String value1 = (String) jsonObject.get(key1);
System.out.println(value);
System.out.println(value1);
}
Cannot read the array length because "keys" is null
RestTemplate
委托基础 Jackson 将 JSON 字符串反序列化为 java 对象。如果您将 HTTP 响应作为通用对象类型获取,它将对其进行反序列化进入 Map
.
您可以简单地创建一个结构与预期的 JSON 响应相同的 POJO,然后使用 Jackson
注释配置如何将 JSON 反序列化为这个 POJO ,并得到 HTTP 响应作为这个 POJO class.
类似于:
public class Result {
@JsonProperty("items")
private List<Item> items = new ArrayList<>();
}
public class Item {
@JsonProperty("kind")
private String kind;
@JsonProperty("etag")
private String etag;
@JsonProperty("snippet")
private List<Snippet> snippets = new ArrayList<>();
}
public class Snippet {
@JsonProperty("channelId")
private String channelId;
@JsonProperty("title")
private String title;
}
然后使用以下命令获取响应:
Result result = rest.getForObject(url, Result.class, params);
获得 Result POJO 后,使用最喜欢的库将其序列化为 XML.
P.S 我只是告诉你一些想法。你必须微调POJO结构
我正在尝试提取使用 YT 数据 API 获得的所有视频的标题、videoId 和描述数据。我能够在 Postman 和 Chrome 浏览器中 return 看起来像 JSON 格式的数据(但当我使用 getClass()
检查时它实际上是 LinkedHashMap),但是无法从我上面提到的特定键中提取值。
我试过了:
System.out.println((rest.getForObject(url, Object.class, params)).get("items"));
它要求我转换为 JSONObject
总的来说,我需要提取数据并将其转换为 xml,然后再将其发送到 ActiveMQ
编辑: 我在 Postman/Chrome 浏览器
中获取的格式{
"kind": "youtube#searchListResponse",
"etag": "3LV4enCWAzOaiqJb_cMIUVklXJY",
"nextPageToken": "CAUQAA",
"regionCode": "CA",
"pageInfo": {
"totalResults": 478712,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "gt6x7J2XpzU8Mpb3yv9_HmNTzWY",
"id": {
"kind": "youtube#video",
"videoId": "I_ZK0t9-llo"
},
"snippet": {
"publishedAt": "2021-03-01T18:15:13Z",
"channelId": "UC2WHjPDvbE6O328n17ZGcfg",
"title": "Stack Overflow is full of idiots.",
"description": "The Stack Overflow culture needs to be fixed. The overall gatekeeping & elitism in computer science & programming - as a whole ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "ForrestKnight",
"liveBroadcastContent": "none",
"publishTime": "2021-03-01T18:15:13Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "RwmGP1qMzUCzK6oV82s0NUEOETw",
"id": {
"kind": "youtube#video",
"videoId": "sMIslcynm0Q"
},
"snippet": {
"publishedAt": "2021-03-07T16:00:13Z",
"channelId": "UCXwjZTvpFiBl93ACCUh1NXQ",
"title": "How To Use Stack Overflow (no, ForrestKnight, it's not full of idiots)",
"description": "Hey everyone, I can't believe I have to make this video. Unfortunately ForrestKnight recently made a video saying Stack Overflow ...",
"thumbnails": {
...
Edit2:我试过了
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
JSONArray array = jsonObject.getJSONArray("items" );
for(int i=0;i<array.length();i++){
JSONObject snippet =array.getJSONObject(i);
System.out.println(snippet.getJSONObject("snippet").get("title"));
}
JSONObject["items"] not found.
编辑3: 我也试过没有 Edit2 和只是
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
System.out.println(jsonObject);
没有错误,我正要获取 Postman 中显示的数据。但是在控制台中打印 {}
,这意味着我可能没有获得数据并且无法提取。
我尝试使用 .get 提取 System.out.println(jsonObject.get("items"));
我得到了同样的错误 JSONObject["items"] not found.
似乎可能是格式错误,它看起来又像 json 了,为了使用 .get,我把它放在 jsonObject 中,但什么也没找到
Edit4:我可以使用
确认我得到的数据是Json(就像文档上说的那样)try {
new JSONObject(rest.getForObject(url, Object.class, params));
} catch (JSONException ex) {
// edited, to include @Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(rest.getForObject(url, Object.class, params));
} catch (JSONException ex1) {
return false;
}
}
return true;
返回真值
Edit5:尝试后似乎键为空
String[] keys = JSONObject.getNames(jsonObject);
// iterate over them
for (String key1 : keys) {
// retrieve the values
Object value = jsonObject.get(key1);
// if you just have strings:
String value1 = (String) jsonObject.get(key1);
System.out.println(value);
System.out.println(value1);
}
Cannot read the array length because "keys" is null
RestTemplate
委托基础 Jackson 将 JSON 字符串反序列化为 java 对象。如果您将 HTTP 响应作为通用对象类型获取,它将对其进行反序列化进入 Map
.
您可以简单地创建一个结构与预期的 JSON 响应相同的 POJO,然后使用 Jackson
注释配置如何将 JSON 反序列化为这个 POJO ,并得到 HTTP 响应作为这个 POJO class.
类似于:
public class Result {
@JsonProperty("items")
private List<Item> items = new ArrayList<>();
}
public class Item {
@JsonProperty("kind")
private String kind;
@JsonProperty("etag")
private String etag;
@JsonProperty("snippet")
private List<Snippet> snippets = new ArrayList<>();
}
public class Snippet {
@JsonProperty("channelId")
private String channelId;
@JsonProperty("title")
private String title;
}
然后使用以下命令获取响应:
Result result = rest.getForObject(url, Result.class, params);
获得 Result POJO 后,使用最喜欢的库将其序列化为 XML.
P.S 我只是告诉你一些想法。你必须微调POJO结构