From 535fbb67682d2fb7afa8b2df0140d22957dd5291 Mon Sep 17 00:00:00 2001 From: caadiq Date: Sat, 7 Feb 2026 20:08:59 +0900 Subject: [PATCH] =?UTF-8?q?feat(x):=20Nitter=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fetchProfile() 함수 추가: username으로 프로필 정보 조회 - displayName, avatarUrl 반환 Co-Authored-By: Claude Opus 4.5 --- backend/src/services/x/scraper.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/backend/src/services/x/scraper.js b/backend/src/services/x/scraper.js index d2042a3..390d035 100644 --- a/backend/src/services/x/scraper.js +++ b/backend/src/services/x/scraper.js @@ -218,6 +218,32 @@ export async function fetchSingleTweet(nitterUrl, username, postId) { }; } +/** + * Nitter에서 프로필 정보만 조회 + */ +export async function fetchProfile(nitterUrl, username) { + const url = `${nitterUrl}/${username}`; + const res = await fetchWithTimeout(url); + const html = await res.text(); + + // 프로필이 존재하는지 확인 + if (html.includes('Error: User') || html.includes('User not found')) { + throw new Error('사용자를 찾을 수 없습니다'); + } + + const profile = extractProfile(html); + + if (!profile.displayName) { + throw new Error('프로필 정보를 가져올 수 없습니다'); + } + + return { + username, + displayName: profile.displayName, + avatarUrl: profile.avatarUrl, + }; +} + /** * Nitter에서 트윗 수집 (첫 페이지만) */