상세 컨텐츠

본문 제목

나만의 유튜브(youtube)맹글깅

스프링

by e7e 2023. 2. 3. 15:20

본문

먼저 아작스 Cross-Origin Same Origin 정책을 극복하기 위해서 

울 서버에서 바로 외부 URL을 요청하고 내용을 돌려줄 수 있는(우회) 라이브러리를 설치

여기선 아파치 httpclient5를 설치(fluent는 더 짧고 편하게 쓸 수 있도록 해주는 라이브러리)

	    <!--  서버단에서 외부 서버URL 요청 -->
		<dependency>
			<groupId>org.apache.httpcomponents.client5</groupId>
			<artifactId>httpclient5</artifactId>
			<version>5.2.1</version>
		</dependency>

		<dependency>
			<groupId>org.apache.httpcomponents.client5</groupId>
			<artifactId>httpclient5-fluent</artifactId>
			<version>5.2.1</version>
		</dependency>

 

포인또는 아래  첫번째 유투브 URL을 이용하여  검색내용에서 관련 영상 코드를 수집하고

해당코드를 두번째  URL을 이용하여 해당 영상코드의 제목을 찾아오는 것

https://www.youtube.com/results?search_query=검색어

https://www.youtube.com/watch?v=영상코드(11자리)

 

컨트롤러 맹글기

package com.jaehan.dumb.controller;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

import org.apache.hc.client5.http.fluent.Request;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequestMapping("/youtube")
public class YoutubeController {

	@GetMapping("/main")
	public String youMain() {
		return "myYoutube";
	}
	
	@GetMapping("/search")
	@ResponseBody
	public String schYoutube(String schWord) throws Exception {
		
		//log.debug("schWord:" + URLEncoder.encode(schWord, "UTF-8"));
		return Request.get("https://www.youtube.com/results?search_query="+URLEncoder.encode(schWord, "UTF-8"))
	    .execute().returnContent().toString();
	}
	
	@GetMapping(value="/schTitle",produces = "text/plain;charset=utf-8")
	@ResponseBody
	public String schTitle(String schCode, HttpServletResponse res) throws Exception {
		//res.setCharacterEncoding("UTF-8");
		log.debug("schCode:" + schCode);
		return Request.get("https://www.youtube.com/watch?v="+schCode)
	    .execute().returnContent().toString();
	}

}

jsp 맹글기

주석처리된 부분은 검색된 내용을 배열에 담으려 했음.(필요하다면 사용)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a e-7-e 유투브</title>
<style>
  select {
    font-size: 1.1em;
  }
</style>
</head>
<body>
	<h1>이것은  유투브를 긁어서 맹근 E-7-E 유투브 </h1>
	<h3>장점은 광고에 거의 노출이 안됨 </h1>
	<h3>단점은 영상 메타정보가 부족하여,자동화가 어려움(다음영상재생등)</h1>
	<input type=text value="로제" id="schTxt" placeholder="껌색어 써 주삼" onkeydown="f_enter()"><input type=button value="찾깅" onclick="y_sch()"><br>
  <div id="list"></div><br><hr>
  <iframe width="1280" id="utube" height="720" src="" title="" frameborder="1" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<script>
  const utubeURL ="https://www.youtube.com/embed/" 
  const jutube = document.querySelector("#utube");
  const sTxt = document.querySelector("#schTxt");
  const jlist = document.querySelector("#list");
  let arrTitle;
  let codeArr;
  let jsel;

  let conEnter = true;
  const f_enter = ()=>{

    if(conEnter && event.keyCode == 13){
    	  if(sTxt.value.trim()=="" || sTxt.value.length < 2){
       			alert("당신은 껌색 바봉");
       			return;
    		}
    	
       y_sch();
       sTxt.value="";
       conEnter = false;
       setTimeout(()=>{    // 엔터를 막 누르는 사람을 막기 위함!
        conEnter = true;
        sTxt.focus();
       },5000)
    }
  }


  const y_tleSch=(p_code)=>{
    //console.log("체킁!");
    let xhr = new XMLHttpRequest();
    xhr.open("get",`/dumb/youtube/schTitle?schCode=\${p_code}`,true);
    xhr.onreadystatechange = () => {
      if(xhr.readyState == 4 && xhr.status == 200){
        let schContent=xhr.responseText;
        let startIndex = schContent.indexOf("<title>");
        let endIndex = schContent.indexOf("</title>");

//        let startIndex1 = schContent.indexOf('<span class="ytp-time-duration">',0);
//        console.log(startIndex1);
//        console.log("체킁:",schContent.substring(startIndex1,startIndex+50));

        let joption = document.createElement("option");
        joption.value = p_code;
        joption.innerHTML = `\${schContent.substring(startIndex+7,endIndex)}`;
        jsel.appendChild(joption); 
        jlist.appendChild(jsel);
         
        //console.log("체킹....",jutube.src);
        if(jutube.src == location.href){
          jutube.src = utubeURL + p_code + "?autoplay=1&mute=1";
          console.log(jutube.src);

          //<span class="ytp-time-duration">1:12:39</span>
          setTimeout(()=>{
            console.log(jutube.contentDocument.getElementsByClassName("ytp-time-duration"));
          },5000);
        }

        //arrTitle.push(`\${schContent.substring(startIndex+7,endIndex)}`);
        /*
        if(arrTitle.length == codeArr.length){
          console.log(codeArr);
          arrTitle.forEach((sTitle)=>{
            let h1 = document.createElement("h1");
            h1.innerHTML = sTitle;
            disp.appendChild(h1);
          })
        }
        */
      }
    }
    xhr.send();
  }
  
  const y_sch = ()=>{
    arrTitle = [];
    codeArr = [];
    jlist.innerHTML = "";
    jutube.src = "";
    let schWord = encodeURIComponent(sTxt.value);
    let xhr = new XMLHttpRequest();
    xhr.open("get",`/dumb/youtube/search?schWord=\${schWord}`,true);
    xhr.onreadystatechange = () => {

      if(xhr.readyState == 4 && xhr.status == 200){
        let schContent=xhr.responseText; // unicode -> utf-8?
        let sIndex = 250000;
       //console.log("시작체킁:",sIndex);

       jsel = document.createElement("select");
       jsel.onchange = ()=>{
            jutube.src = utubeURL + jsel.value + "?autoplay=1&mute=1";
       }
       while( (startIndex = schContent.indexOf("watch?v=",sIndex)) != -1){
          let sCode = schContent.substr(startIndex+8,11);
          sIndex = startIndex + 5000;
          //console.log("s인덱스:",sIndex)
          //console.log("s코드:",sCode);
          if( codeArr.indexOf(sCode) == -1){
            y_tleSch(sCode);  // 찾고 바로 부르면 좋겠지만, 종료 조건이 애매
            //codeArr.push(sCode);
          }
       }
       /*
       codeArr.forEach((sCode)=>{
          y_tleSch(sCode);
       });
       console.log("최종",codeArr);
       */
      }
    }
    xhr.send();
  }
  
</script>
</body>
</html>

결과(생각보다 어렵지 않아용!)

 

 

맘에 걸리면 ,오래두면 맘을 썩게 할거당.

자백해서  덜어내고 잘라내야 한당.

때론 사과가 부담스러울 수 있당. 안당.

삶을 버티려면  후딱 사과하고 자백해야 한당.

 

착한 척을 하다가 착해져라.

그거시 이기심을 충족시킬 효율적 방법 중 하나당.! 

 

 

https://www.youtube.com/watch?v=3PuvxiPIJjQ

 

'스프링' 카테고리의 다른 글

이클립스 패키지 <-> 폴더 바꾸깅  (0) 2023.08.29
외부 파일 맵핑  (0) 2023.02.24
파일 업로드  (0) 2023.01.02
Apache POI  (0) 2022.11.16
STS3(Spring Tool Suite) 설치  (0) 2022.10.20

관련글 더보기