214 lines
9.5 KiB
Python
Executable File
214 lines
9.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
News Aggregator Service Test
|
|
RSS 피드 제목을 구글 full content 검색으로 확장하는 통합 테스트
|
|
"""
|
|
import asyncio
|
|
import httpx
|
|
import json
|
|
from datetime import datetime
|
|
from typing import Dict, Any
|
|
|
|
# Service URL
|
|
SERVICE_URL = "http://localhost:8018"
|
|
|
|
async def test_aggregate_with_full_content():
|
|
"""키워드로 RSS 피드를 검색하고 full content 구글 검색 테스트"""
|
|
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
print("\n" + "="*60)
|
|
print("뉴스 통합 서비스 Full Content 테스트")
|
|
print("="*60)
|
|
|
|
# Test with keyword "인공지능"
|
|
print("\n1. 키워드 '인공지능'으로 RSS 피드 검색 및 구글 full content 검색")
|
|
print("-" * 40)
|
|
|
|
response = await client.get(
|
|
f"{SERVICE_URL}/api/aggregate",
|
|
params={
|
|
"q": "인공지능",
|
|
"limit": 3, # 테스트용으로 3개만
|
|
"google_results_per_title": 2, # 각 제목당 2개 구글 결과
|
|
"lang": "ko",
|
|
"country": "KR"
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✓ RSS 피드 URL: {data['rss_feed_url']}")
|
|
print(f"✓ 전체 RSS 항목 수: {data['total_rss_entries']}")
|
|
print(f"✓ 처리된 항목 수: {data['processed_entries']}")
|
|
print(f"✓ 처리 시간: {data['processing_time']:.2f}초")
|
|
|
|
# Check each news item for full content
|
|
for i, item in enumerate(data['news_items'], 1):
|
|
print(f"\n [{i}] RSS 제목: {item['rss_title'][:50]}...")
|
|
print(f" 검색 키워드: {item['search_keyword'][:50]}...")
|
|
print(f" 구글 검색 결과 수: {len(item['google_results'])}")
|
|
|
|
# Check if google results have full_content
|
|
for j, result in enumerate(item['google_results'], 1):
|
|
has_full_content = 'full_content' in result
|
|
if has_full_content:
|
|
full_content = result.get('full_content', '')
|
|
if isinstance(full_content, str):
|
|
content_length = len(full_content)
|
|
else:
|
|
content_length = len(str(full_content))
|
|
else:
|
|
content_length = 0
|
|
|
|
print(f" - 결과 {j}: {result.get('title', 'N/A')[:40]}...")
|
|
print(f" Full Content 포함: {'✓' if has_full_content else '✗'}")
|
|
if has_full_content:
|
|
print(f" Content 길이: {content_length:,} 문자")
|
|
# Show first 200 chars of content
|
|
if isinstance(result['full_content'], str):
|
|
preview = result['full_content'][:200].replace('\n', ' ')
|
|
print(f" 미리보기: {preview}...")
|
|
else:
|
|
print(f" Content 타입: {type(result['full_content'])}")
|
|
print(f" Content 데이터: {str(result['full_content'])[:200]}...")
|
|
else:
|
|
print(f"✗ 오류: {response.status_code}")
|
|
print(f" 상세: {response.text}")
|
|
|
|
async def test_aggregate_by_location():
|
|
"""지역 기반 RSS 피드 및 full content 테스트"""
|
|
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
print("\n" + "="*60)
|
|
print("지역 기반 뉴스 통합 Full Content 테스트")
|
|
print("="*60)
|
|
|
|
print("\n2. 지역 'Seoul'로 RSS 피드 검색 및 구글 full content 검색")
|
|
print("-" * 40)
|
|
|
|
response = await client.get(
|
|
f"{SERVICE_URL}/api/aggregate/location",
|
|
params={
|
|
"location": "Seoul",
|
|
"limit": 2,
|
|
"google_results_per_title": 2,
|
|
"lang": "ko",
|
|
"country": "KR"
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✓ 지역: {data['keyword']}")
|
|
print(f"✓ RSS 피드 URL: {data['rss_feed_url']}")
|
|
print(f"✓ 처리된 항목 수: {data['processed_entries']}")
|
|
|
|
# Check full content availability
|
|
full_content_count = 0
|
|
total_content_size = 0
|
|
|
|
for item in data['news_items']:
|
|
for result in item['google_results']:
|
|
if 'full_content' in result:
|
|
full_content_count += 1
|
|
content = result['full_content']
|
|
if isinstance(content, str):
|
|
total_content_size += len(content)
|
|
else:
|
|
total_content_size += len(str(content))
|
|
|
|
print(f"\n📊 Full Content 통계:")
|
|
print(f" - Full Content 포함 결과: {full_content_count}개")
|
|
print(f" - 전체 Content 크기: {total_content_size:,} 문자")
|
|
print(f" - 평균 Content 크기: {total_content_size//max(full_content_count, 1):,} 문자")
|
|
else:
|
|
print(f"✗ 오류: {response.status_code}")
|
|
|
|
async def test_aggregate_by_topic():
|
|
"""주제별 RSS 피드 및 full content 테스트"""
|
|
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
print("\n" + "="*60)
|
|
print("주제별 뉴스 통합 Full Content 테스트")
|
|
print("="*60)
|
|
|
|
print("\n3. 주제 'TECHNOLOGY'로 RSS 피드 검색 및 구글 full content 검색")
|
|
print("-" * 40)
|
|
|
|
response = await client.get(
|
|
f"{SERVICE_URL}/api/aggregate/topic",
|
|
params={
|
|
"category": "TECHNOLOGY",
|
|
"limit": 2,
|
|
"google_results_per_title": 3,
|
|
"lang": "ko",
|
|
"country": "KR"
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✓ 주제: {data['keyword']}")
|
|
print(f"✓ 처리 시간: {data['processing_time']:.2f}초")
|
|
|
|
# Analyze content quality for AI summarization
|
|
print("\n📝 AI 요약을 위한 Content 품질 분석:")
|
|
for i, item in enumerate(data['news_items'], 1):
|
|
print(f"\n 뉴스 항목 {i}:")
|
|
for j, result in enumerate(item['google_results'], 1):
|
|
if 'full_content' in result:
|
|
content = result['full_content']
|
|
if isinstance(content, str):
|
|
# Check content quality indicators
|
|
has_paragraphs = '\n\n' in content or '</p>' in content
|
|
has_sufficient_length = len(content) > 500
|
|
has_korean = any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in content[:min(100, len(content))])
|
|
else:
|
|
content_str = str(content)
|
|
has_paragraphs = '\n\n' in content_str or '</p>' in content_str
|
|
has_sufficient_length = len(content_str) > 500
|
|
has_korean = any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in content_str[:min(100, len(content_str))])
|
|
|
|
print(f" 결과 {j} 품질 체크:")
|
|
print(f" - 충분한 길이 (>500자): {'✓' if has_sufficient_length else '✗'}")
|
|
print(f" - 단락 구조 포함: {'✓' if has_paragraphs else '✗'}")
|
|
print(f" - 한국어 콘텐츠: {'✓' if has_korean else '✗'}")
|
|
print(f" - AI 요약 가능: {'✓' if (has_sufficient_length and has_paragraphs) else '✗'}")
|
|
else:
|
|
print(f"✗ 오류: {response.status_code}")
|
|
|
|
async def test_health_check():
|
|
"""서비스 상태 확인"""
|
|
async with httpx.AsyncClient() as client:
|
|
print("\n" + "="*60)
|
|
print("서비스 Health Check")
|
|
print("="*60)
|
|
|
|
response = await client.get(f"{SERVICE_URL}/health")
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✓ 통합 서비스 상태: {data['status']}")
|
|
print(f" - RSS 서비스: {data['services']['rss_feed']}")
|
|
print(f" - Google 검색 서비스: {data['services']['google_search']}")
|
|
else:
|
|
print(f"✗ Health check 실패: {response.status_code}")
|
|
|
|
async def main():
|
|
"""메인 테스트 실행"""
|
|
print("\n" + "="*70)
|
|
print(" News Aggregator Full Content Integration Test ")
|
|
print(" RSS 피드 + Google Full Content 통합 테스트 ")
|
|
print("="*70)
|
|
|
|
# Run tests
|
|
await test_health_check()
|
|
await test_aggregate_with_full_content()
|
|
await test_aggregate_by_location()
|
|
await test_aggregate_by_topic()
|
|
|
|
print("\n" + "="*70)
|
|
print(" 테스트 완료 - Full Content 통합 확인 ")
|
|
print("="*70)
|
|
print("\n✅ 모든 테스트가 완료되었습니다.")
|
|
print(" RSS 피드 제목을 구글 full content로 검색하는 기능이 정상 작동합니다.")
|
|
print(" AI 요약을 위한 충분한 콘텐츠가 수집되고 있습니다.")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |