diff --git a/.gitignore b/.gitignore index fd08fbe..4a843e7 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ oracle_data/ # Claude Code # ======================== .claude/ +cookies.txt diff --git a/sundol-backend/src/main/java/com/sundol/service/YouTubeTranscriptService.java b/sundol-backend/src/main/java/com/sundol/service/YouTubeTranscriptService.java index 8bff2d1..e71276b 100644 --- a/sundol-backend/src/main/java/com/sundol/service/YouTubeTranscriptService.java +++ b/sundol-backend/src/main/java/com/sundol/service/YouTubeTranscriptService.java @@ -14,6 +14,9 @@ import org.springframework.stereotype.Service; import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -118,6 +121,10 @@ public class YouTubeTranscriptService { BrowserContext context = browser.newContext(new Browser.NewContextOptions() .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36") .setLocale("ko-KR")); + + // YouTube 쿠키 로딩 (봇 차단 우회) + loadCookies(context); + Page page = context.newPage(); page.navigate(watchUrl, new Page.NavigateOptions() @@ -218,6 +225,37 @@ public class YouTubeTranscriptService { return sb.toString(); } + private void loadCookies(BrowserContext context) { + Path cookieFile = Path.of(System.getProperty("user.dir"), "cookies.txt"); + if (!Files.exists(cookieFile)) { + log.warn("cookies.txt not found at: {}", cookieFile); + return; + } + + try { + List lines = Files.readAllLines(cookieFile); + List cookies = new ArrayList<>(); + for (String line : lines) { + if (line.startsWith("#") || line.isBlank()) continue; + String[] parts = line.split("\t"); + if (parts.length < 7) continue; + String domain = parts[0]; + if (!domain.contains("youtube") && !domain.contains("google")) continue; + cookies.add(new com.microsoft.playwright.options.Cookie(parts[5], parts[6]) + .setDomain(domain) + .setPath(parts[2]) + .setSecure("TRUE".equalsIgnoreCase(parts[3])) + .setHttpOnly(false)); + } + if (!cookies.isEmpty()) { + context.addCookies(cookies); + log.info("Loaded {} YouTube cookies", cookies.size()); + } + } catch (Exception e) { + log.warn("Failed to load cookies: {}", e.getMessage()); + } + } + private String extractVideoId(String url) { if (url == null || url.isBlank()) return null; try {