web developer

[java] youtube Data API [3] : Search / 여러 개 channel의 검색결과 가져와서 db 입력하기 본문

Language/Java

[java] youtube Data API [3] : Search / 여러 개 channel의 검색결과 가져와서 db 입력하기

trueman 2023. 11. 24. 15:53
728x90
728x90

여러 개 channel에서 키워드 검색을 통한 검색결과를 가져오는 방법

 

(1) keywordSearchData를 호출시키면 youtube channel id 여러개를 youtubeDataAPI 메소드에 전달한다.

 

(2) youtube Data API 할당량이 정해져 있기 때문에 검색결과를 줄이기 위해서 해시태그(#)가 붙여진 유튜브 동영상에 한하여 youtube Data API를 실행되도록 검색어 앞에 '#'를 붙였다.

* youtube Data API의 일일 할당량 10,000

 

(3) youtube Data API 실행된 이후인 2번째부터 nextPageToken 토큰값 있으면 파리미터 추가한다.

* 결과 집합의 다음 페이지를 검색하는 pageToken 매개변수의 값으로 사용할 수 있는 토큰

 

(4) nextPageToken 값이 있으면, youtubeDataAPI 메소드를 다시 실행시키면서 검색결과를 가져올 수 있도록 한다.


Java 
@RequestMapping(value="/keywordSearchData.do", method = RequestMethod.GET)
public void keywordSearchData() throws Exception {
    String nextToken = null;

    // (1) mbc
    String mbcChannelId = "UCF4Wxdo3inmxP-Y59wXDsFw";
    String channelName = "MBC";
    System.out.println("===========================================");
    System.out.println(channelName + " | YOUTUBE DATA API [START]");
    System.out.println("===========================================");
    youtubeDataAPI(nextToken, mbcChannelId, channelName);

    // (2) kbs
    String kbsChannelId = "UCcQTRi69dsVYHN3exePtZ1A";
    channelName = "KBS";
    System.out.println("===========================================");
    System.out.println(channelName + " | YOUTUBE DATA API [START]");
    System.out.println("===========================================");
    youtubeDataAPI(nextToken, kbsChannelId, channelName);

    // (3) sbs
    String sbsChannelId = "UCkinYTS9IHqOEwR1Sze2JTw";
    channelName = "SBS";
    System.out.println("===========================================");
    System.out.println(channelName + " | YOUTUBE DATA API [START]");
    System.out.println("===========================================");
    youtubeDataAPI(nextToken, sbsChannelId, channelName);
}

Java 
	public void youtubeDataAPI(String nextToken, String channelId, String channelName) {

		YoutubeVO youtubeVO = new YoutubeVO();
		StringBuffer response = null;
		int duplication_cnt = 0; // 등록된 유튜브 COUNT 
		int non_duplication_cnt = 0; // 중복된 유튜브 COUNT 
		
		String apiurl = "https://www.googleapis.com/youtube/v3/search";
		String apikey = "발급받은 API KEY";
		String search = "#검색어"; // keyword
		
		// date
		LocalDate nowDate = LocalDate.now();
		LocalDate yesterday = nowDate.minusDays(1); // 하루전 날짜 
		
		/* 시작일
		String startDate = "2023-10-01";
		LocalDate startLocaldate = LocalDate.parse(startDate);
		String startFormatDate = startLocaldate.atStartOfDay().toInstant(ZoneOffset.UTC).toString();
		*/

		// 시작일 // "YYYY-MM-DDT00:00:00Z";     
		String startFormatDate = yesterday.atStartOfDay().toInstant(ZoneOffset.UTC).toString(); 

		// 종료일 //"YYYY-MM-DDT23:59:59Z";
		String endFormatDate = yesterday.atTime(LocalTime.MAX).toInstant(ZoneOffset.UTC).toString();

		// fields
		String fields = "nextPageToken,items(id,snippet(publishedAt,title,description,thumbnails))";
		
		try {
			apiurl += "?key=" + apikey;
			apiurl += "&part=snippet";
			apiurl += "&channelId="+channelId;
			apiurl += "&type=video";
			apiurl += "&maxResults=50"; // 0~50 [기본 5]
			apiurl += "&order=relevance"; // 관련도순 
			apiurl += "&videoEmbeddable=true"; 
			apiurl += "&regionCode=KR"; 
			apiurl += "&q="+URLEncoder.encode(search,"UTF-8"); // keyword
			apiurl += "&publishedAfter="+startFormatDate; // start date 
			apiurl += "&publishedBefore="+endFormatDate;  // end date
			apiurl += "&fields="+URLEncoder.encode(fields,"UTF-8");
			
			// 처음 API 실행시 nextToken은 null값이 들어가게 됨
			if(nextToken != null && !nextToken.equals("")) {
				apiurl += "&pageToken=" + nextToken;
			}
			
			// url 연결
			URL url = new URL(apiurl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("GET");
			
			// 인증서 무시하는 코드 1
			TrustManager[] trustAllCerts = new TrustManager[] {
				new X509TrustManager() {
					
					public java.security.cert.X509Certificate[] getAcceptedIssuers() {
						return null;
					}
					public void checkClientTrusted(X509Certificate[] certs, String authType) {
						
					}
					public void checkServerTrusted(X509Certificate[] certs, String authType) {
						
					}
				}
			};
			
			// 인증서 무시하는 코드 2
			SSLContext context = SSLContext.getInstance("SSL");
			context.init(null, trustAllCerts, new java.security.SecureRandom());
			((HttpsURLConnection) con).setSSLSocketFactory(context.getSocketFactory());
			con.connect();

			// json data 생성
			String result ="";
			BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
			String inputLine;
			response = new StringBuffer();
			while((inputLine = br.readLine()) != null) {
				response.append(inputLine);
			}		    
			br.close();    		

			//String에 담는다.
			result = response.toString();

			//JSONParser
			JSONParser jsonParser = new JSONParser();
			//JSON데이터를 넣어 JSON Object 로 만들어 준다.
			JSONObject jsonObject = (JSONObject) jsonParser.parse(result);
			
			// 다음 페이지 token 존재여부 체크
			if(jsonObject.get("nextPageToken") != null && !jsonObject.get("nextPageToken").equals("")) {
				nextToken = jsonObject.get("nextPageToken").toString();
				System.out.println("토큰값 : " + nextToken);
			}else {
				nextToken = null;
			}
			
			//items 배열을 추출
			JSONArray youtubeArray = (JSONArray) jsonObject.get("items");

			for (int i = 0; i < youtubeArray.size(); i++) {
				JSONObject data = (JSONObject) youtubeArray.get(i);

				// 유튜브 비디오 ID 
				JSONObject id = (JSONObject) data.get("id");
				String videoId = id.get("videoId").toString();
				String youtubeUrl = "https://www.youtube.com/watch?v="+videoId;
				youtubeVO.setUrl(youtubeUrl);
				
				// 유튜브 제목
				JSONObject snippet = (JSONObject) data.get("snippet");
				String title = snippet.get("title").toString();
				youtubeVO.setTitle(HtmlUtils.htmlUnescape(title));
				
				// 유튜브 내용 
				String description = snippet.get("description").toString();
				youtubeVO.setContents(HtmlUtils.htmlUnescape(description));

				// 중복체크
				int check = service.selectDoubleCheck(youtubeVO);
				if(check == 0) { // 중복되지 않고, DB 등록될 경우
					service.insertYoutubeData(youtubeVO);
					non_duplication_cnt++;
				}else { // 중복된 경우 
					duplication_cnt++;
				}
			}
			System.out.println(channelName + " [등록된 유튜브] : " + non_duplication_cnt);
			System.out.println(channelName + " [중복된 유튜브] : " + duplication_cnt);
            
			if(nextToken != null && !nextToken.equals("")) {
				youtubeDataAPI(nextToken, channelId, channelName);
			}else {
				System.out.println("===========================================");
				System.out.println(channelName + " | YOUTUBE DATA API [END]");
				System.out.println("===========================================");
			}
		}catch(Exception e) {
			System.out.println("예외상황 발생");
		}
	}

 


 

728x90
728x90
Comments