YouTube Data API (v3) JAVA で
前準備と、
小一時間まさぐった
参考サイト
Maven Repository: com.google.apis » google-api-services-youtube
Youtube Data API v3 java search with pagination issue - Stack Overflow
前準備
1. APIの 有効かと、 キーの 発行
google developer console
で
search API のみで、
APIキーのみの
[Referer] の
2. maven pom.xml の 記述
Maven Repository: com.google.apis » google-api-services-youtube
で
google alaytics API も
google API の
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-youtube -->
com.google.apis
google-api-services-youtube
v3-rev178-1.22.0
サンプル実装
search を
プログラムの
package xyz.monotalk.batch.utils; import com.google.api.client.http.HttpHeaders; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.youtube.YouTube; import com.google.api.services.youtube.model.SearchListResponse; import com.google.api.services.youtube.model.SearchResult; import xyz.monotalk.batch.apps.BatchRuntimeException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * YoutubeUtils * * @author Kem */ public class YoutubeUtils { private static final String API_KEY = "xxx"; /** * Global instance of the HTTP transport. */ private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); /** * Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = new JacksonFactory(); /** * Global instance of the max number of videos we want returned (50 = upper limit per page). */ private static final long NUMBER_OF_VIDEOS_RETURNED = 25; /** * Global instance of Youtube object to make all API requests. */ private static YouTube youtube; /** * searchVideo * * @param query * @return */ public static List searchVideo(String query) { youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, new HttpRequestInitializer() { public void initialize(HttpRequest request) throws IOException { } }).setApplicationName("yourAppName").build(); List searchResultList = new ArrayList<>(); String queryTerm = query; YouTube.Search.List search = null; try { search = youtube.search().list("id,snippet"); } catch (IOException e) { throw new BatchRuntimeException(e); } search.setKey(API_KEY); search.setQ(queryTerm); search.setType("video"); // 1.検索結果フィールドに"nextPageToken"を指定 search.setFields("items(*),nextPageToken"); HttpHeaders headers = new HttpHeaders(); // 2."Referer" に 稼働させる予定のドメイン名を指定 headers.set("Referer", "www.yourdomain.com/example"); headers.setContentType("application/json"); search.setRequestHeaders(headers); search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED); SearchListResponse searchResponse = null; do { if (searchResponse != null && searchResponse.getNextPageToken() != null) { search.setPageToken(searchResponse.getNextPageToken()); } try { searchResponse = search.execute(); } catch (IOException e) { throw new BatchRuntimeException(e); } println("START---------------------"); try { println(searchResponse.toPrettyString()); println(searchResponse.getNextPageToken()); } catch (IOException e) { e.printStackTrace(); } println("END-----------------------"); searchResultList.addAll(searchResponse.getItems()); // 検索結果の有無しは、searchResponse.getItems().isEmpty() で判定する // この実装だと、loopが1回余分に回るがあまり気にしないでおく。 } while (!searchResponse.getItems().isEmpty()); return searchResultList; } private static void println(String msg) { System.out.println(msg); } }
特記事項1
検索結果フィールドに
次ページ検索用の
PageTokenは
特記事項2
APIキー発行時に、
headers.set("Referer", "www.yourdomain.com/example");
で
※偽装が
特記事項3
ページングの
searchResponse.getItems().isEmpty()
を
結果が
検索結果の
補足
1. nextPageToken が Null か どうかで do-while-loopすると どうなるか?
最終的に
START--------------------- { "items" : [ ], "nextPageToken" : "CLYHEAA" } CLYHEAA END----------------------- START--------------------- { "items" : [ ], "nextPageToken" : "CM8HEAA" } CM8HEAA END----------------------- START--------------------- { "items" : [ ] } null END-----------------------
2. while (!searchResponse.isEmpty())
で do-while-loopすると どうなるか?
最終的に
こちらは"nextPageToken"
が
START--------------------- { "items" : [ ], "nextPageToken" : "CLYHEAA" } CLYHEAA END----------------------- START--------------------- { "items" : [ ], "nextPageToken" : "CM8HEAA" } CM8HEAA END----------------------- START--------------------- { "items" : [ ] } null END-----------------------
3. Referer の 記載を 誤った 場合の エラー
headers.set("Referer","www.yourdomain.com/example");
の
※403エラーと
xyz.monotalk.batch.apps.BatchRuntimeException: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden { "code" : 403, "errors" : [ { "domain" : "usageLimits", "message" : "The referrer www.xxxxxxxxxx.xyz/example does not match the referrer restrictions configured on your API key. Please use the API Console to update your key restrictions.", "reason" : "ipRefererBlocked", "extendedHelp" : "https://console.developers.google.com/apis/credentials?project=xxxxxxxxxxxxxx" } ], "message" : "The referrer www.xxxxxxxxxx.xyz/example does not match the referrer restrictions configured on your API key. Please use the API Console to update your key restrictions." } at xyz.monotalk.batch.utils.YoutubeUtils.searchVideo(YoutubeUtils.java:79) at xyz.monotalk.batch.utils.YoutubeUtilsTest.testSearchVideo(YoutubeUtilsTest.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Echonest APIだと、
便利だった?のですが、
勉強に
以上です。
コメント