/g, '\n') + // 태그: href에서 원본 URL 추출 (외부 링크만) + .replace(/]*href="([^"]*)"[^>]*>([^<]*)<\/a>/g, (match, href, text) => { + // Nitter 내부 링크 (/search, /hashtag 등)는 표시 텍스트 사용 + if (href.startsWith('/')) { + return text; + } + // 외부 링크는 href의 원본 URL 사용 + return href; + }) + .replace(/<[^>]+>/g, '') + .trim(); +} + /** * HTML에서 트윗 목록 파싱 */ @@ -106,11 +125,7 @@ export function parseTweets(html, username) { const contentMatch = container.match(/
/g, '\n') - .replace(/]*>([^<]*)<\/a>/g, '$1') - .replace(/<[^>]+>/g, '') - .trim(); + text = extractTextFromHtml(contentMatch[1]); } // 이미지 @@ -157,11 +172,7 @@ export async function fetchSingleTweet(nitterUrl, username, postId) { const contentMatch = container.match(/
/g, '\n') - .replace(/]*>([^<]*)<\/a>/g, '$1') - .replace(/<[^>]+>/g, '') - .trim(); + text = extractTextFromHtml(contentMatch[1]); } // 이미지