""" PubMed 논문 검색 테스트 Biopython Entrez를 사용한 의학 논문 검색 """ import sys import os # UTF-8 인코딩 강제 (Windows 한글 깨짐 방지) if sys.platform == 'win32': import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') from Bio import Entrez from dotenv import load_dotenv # .env 파일 로드 load_dotenv() # NCBI Entrez 설정 Entrez.email = os.getenv('PUBMED_EMAIL', 'test@example.com') api_key = os.getenv('PUBMED_API_KEY') if api_key: Entrez.api_key = api_key print(f"[INFO] PubMed API Key 사용 중 (최대 10 req/sec)") else: print(f"[INFO] API Key 없음 (최대 3 req/sec 제한)") def search_pubmed(query, max_results=5): """PubMed에서 논문 검색""" try: print(f"\n검색어: '{query}'") print("-" * 80) # 1. 검색 (PMID 목록 가져오기) handle = Entrez.esearch( db="pubmed", term=query, retmax=max_results, sort="relevance" ) record = Entrez.read(handle) handle.close() pmids = record["IdList"] total_count = int(record["Count"]) if not pmids: print(f"[WARNING] 검색 결과 없음") return [] print(f"[OK] 총 {total_count}건 검색됨, 상위 {len(pmids)}건 조회 중...\n") # 2. 논문 상세 정보 가져오기 handle = Entrez.efetch( db="pubmed", id=pmids, rettype="medline", retmode="xml" ) papers = Entrez.read(handle) handle.close() results = [] for idx, paper in enumerate(papers['PubmedArticle'], 1): try: article = paper['MedlineCitation']['Article'] # PMID pmid = str(paper['MedlineCitation']['PMID']) # 제목 title = article.get('ArticleTitle', '(제목 없음)') # 초록 (여러 섹션이 있을 수 있음) abstract_parts = article.get('Abstract', {}).get('AbstractText', []) if abstract_parts: if isinstance(abstract_parts, list): abstract = ' '.join([str(part) for part in abstract_parts]) else: abstract = str(abstract_parts) else: abstract = "(초록 없음)" # 저널 journal = article.get('Journal', {}).get('Title', '(저널 없음)') # 출판 연도 pub_date = article.get('Journal', {}).get('JournalIssue', {}).get('PubDate', {}) year = pub_date.get('Year', '(연도 없음)') # 저자 (첫 번째 저자만) authors = article.get('AuthorList', []) if authors: first_author = authors[0] last_name = first_author.get('LastName', '') initials = first_author.get('Initials', '') author_str = f"{last_name} {initials}" if last_name else "(저자 없음)" else: author_str = "(저자 없음)" result = { 'pmid': pmid, 'title': title, 'abstract': abstract[:500] + '...' if len(abstract) > 500 else abstract, 'journal': journal, 'year': year, 'author': author_str } results.append(result) # 출력 print(f"[{idx}] PMID: {pmid}") print(f"제목: {title}") print(f"저자: {author_str}") print(f"저널: {journal} ({year})") print(f"초록: {result['abstract']}") print(f"링크: https://pubmed.ncbi.nlm.nih.gov/{pmid}/") print("-" * 80) except Exception as e: print(f"[ERROR] 논문 파싱 실패: {e}") continue return results except Exception as e: print(f"[ERROR] PubMed 검색 실패: {e}") return [] def main(): """메인 실행""" print("=" * 80) print("PubMed 논문 검색 테스트") print("=" * 80) # 테스트 1: Statin과 CoQ10 관계 print("\n[TEST 1] Statin과 CoQ10 근육 부작용 관계") results1 = search_pubmed("statin AND coq10 AND muscle", max_results=3) # 테스트 2: CoQ10 일반 print("\n[TEST 2] CoQ10 보충제 효능") results2 = search_pubmed("coenzyme q10 supplementation benefits", max_results=3) # 테스트 3: 약물 상호작용 print("\n[TEST 3] Atorvastatin 부작용") results3 = search_pubmed("atorvastatin adverse effects", max_results=3) print("\n" + "=" * 80) print("검색 완료") print("=" * 80) print(f"총 {len(results1) + len(results2) + len(results3)}개 논문 조회됨") print("\n[TIP] GraphRAG에 활용 방법:") print(" 1. 검색된 PMID를 지식 그래프에 저장") print(" 2. AI 추천 시 관련 논문 인용") print(" 3. 예시: 'Statin 복용자에게 CoQ10 추천 (근거: PMID:12345678, 신뢰도: 85%)'") if __name__ == '__main__': main()