네이버 뉴스 기사를 크롤링하고, LangChain을 활용한 RAG 구현 실습
구글 Colab 사용
1. 데이터 크롤링
참고 : https://wingyu-story.tistory.com/4
Python 파이썬 오픈api 로 네이버 뉴스 크롤링 (1)
참고 문헌 : IT CookBook, 데이터 과학 기반의 파이썬 빅데이터 분석(이지영), 네이버api 문서 소스코드는 참고 문헌을 통해 가져왔습니다. Python 파이썬으로 api 로 네이버 기사 크롤링 Crawling하는 법
wingyu-story.tistory.com
1. 크롬 드라이브 연결
from google.colab import drive
drive.mount('/content/drive')
2. 라이브러리
import os
import sys
import urllib.request
import datetime
import time
import json
import html
3. 네이버 api key json으로 저장해놓고, 불러오기
# naver api key 설정
with open("./drive/MyDrive/실습/RAG/api_key.json", 'r') as j :
json_key = json.load(j)
client_id = json_key['client_id']
client_secret = json_key['client_secret']
4. 뉴스 기사 크롤링 코드
def getRequestUrl(url) :
req = urllib.request.Request(url)
req.add_header("X-Naver-Client-Id", client_id)
req.add_header("X-Naver-Client-Secret", client_secret)
try :
response = urllib.request.urlopen(req)
if response.getcode() == 200 :
print("[%s] Url Request Success" % datetime.datetime.now())
return response.read().decode('utf-8')
except Exception as e :
print(e)
print("[%s] Error for URL : %s" %(datetime.datetime.now(), url))
return None
def getNaverSearch(node, srcText, start, display) :
base = "https://openapi.naver.com/v1/search/"
node = "%s.json" % node
parameters = "?query=%s&start=%s&display=%s" %(urllib.parse.quote(srcText), start, display)
url = base + node + parameters
responseDecode = getRequestUrl(url)
if (responseDecode == None) :
return None
else :
return json.loads(responseDecode)
def clean_text(text):
# 유니코드 이스케이프 → 실제 문자로
# text = text.encode('utf-8').decode('unicode_escape')
# HTML 엔티티 디코드 (& 등)
text = html.unescape(text)
# 간단한 HTML 태그 제거 (<b> 등)
import re
text = re.sub(r'<[^>]+>', '', text)
return text
def getPostData(post, jsonResult, cnt) :
title = clean_text(post['title'])
description = clean_text(post['description'])
org_link = post['originallink']
link = post['link']
pDate = datetime.datetime.strptime(post['pubDate'], '%a, %d %b %Y %H:%M:%S +0900')
pDate = pDate.strftime('%Y-%m-%d %H:%M:%S')
jsonResult.append({'cnt' : cnt, 'title': title, 'description' : description,
'org_link' : org_link, 'link' : org_link, 'pDate' : pDate})
return
def getNews(src) :
node = 'news' # 크롤링 대상
srcText = src
cnt = 0
jsonResult = []
jsonResponse = getNaverSearch(node, srcText, 1, 100)
print(jsonResponse)
total = jsonResponse['total']
while ((jsonResponse != None) and (jsonResponse['display'] != 0)) :
for post in jsonResponse['items'] :
cnt += 1
getPostData(post, jsonResult, cnt)
start = jsonResponse['start'] + jsonResponse['display']
jsonResponse = getNaverSearch(node, srcText, start, 100)
print("전체 검색 : %d 건" %total)
with open('./drive/MyDrive/실습/RAG/data/%s_naver_%s.json' %(srcText, node), 'w', encoding='utf-8') as output :
jsonFile = json.dumps(jsonResult, indent=4, sort_keys=True, ensure_ascii=False)
output.write(jsonFile)
print("가져온 데이터 : %d 건" %(cnt))
print("%s_naver_%s.json SAVED" %(srcText, node))
5. 뉴스 기사 크롤링하기
getNews('lck')
getNews('살인')
getNews('금리')
...
2. LangChain
참고 :
https://day-to-day.tistory.com/76
Basic RAG를 실습 코드와 함께 알아보기 (feat. llamaIndex, langchain)
들어가며RAG를 사용해야 하는 이유RAG의 패러다임 (RAG 변천사)Naive RAG의 구조langchain과 llamaIndex를 활용한 chromaDB로 Naive RAG 구현하기 What is RAG(Retrieval-Augmented Generation)?전통적인 LLM들은 특정 시점의
day-to-day.tistory.com
https://creboring.net/blog/how-to-use-jq/
[Linux] jq로 느낌 있게 JSON 데이터 가공하기
jq의 사용법과 실제 사용 사례들을 알아보자
creboring.net
https://python.langchain.com/api_reference/
Search - 🦜🔗 LangChain documentation
python.langchain.com
https://cheatsheet.md/ko/langchain-tutorials/langchain-load-json
Langchain에서 JSON 파일을로드하는 방법 - 단계별 가이드 – AI StartUps Product Information, Reviews, Latest Upd
Langchain로드 JSON을 마스터하기위한 효율적인 데이터 처리 방법을 알아보십시오.이 포괄적인 가이드에서는 기본 사항, 일반적인 문제 및 실제 작동 코드와 함께 실제 예제를 통해 안내합니다. 놓
cheatsheet.md
1. 패키지 설치
!pip install -qU "langchain[openai]"
!pip install -qU langchain-openai
!pip install -qU langchain-core
!pip install -qU langgraph
!pip install -qU langchain_community
!pip install -qU jq
!pip install -qU langchain_chroma
!pip install -qU langchain_experimental
!pip install -qU langchain
2. OpenAI에서 api key 생성 후 json 파일 생성. 이후 key 불러오기
import os
import getpass
# openai api key 설정
with open("./drive/MyDrive/실습/RAG/openai_api_key.json", 'r') as j :
openai_key = json.load(j)
os.environ["OPENAI_API_KEY"] = openai_key['OPENAI_API_KEY']
3. json data path 저장
data_path = './drive/MyDrive/실습/RAG/data/'
json_paths = [data_path + json_file for json_file in os.listdir(data_path)]
4. Json 데이터 ChromaDB에 저장 ... //제목 : / 날짜 : / 기사 : // 라고 저장해뒀으면 인용 도큐먼트 내용이 더 잘 나왔을 듯
from langchain_openai import OpenAIEmbeddings
from langchain_community.document_loaders import JSONLoader
from langchain_chroma import Chroma
# embedding 설정
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
# ChromaDB Path
DB_PATH = "./drive/MyDrive/실습/RAG/db"
# Json 파일 Path
data_path = './drive/MyDrive/실습/RAG/data/'
json_paths = [data_path + json_file for json_file in os.listdir(data_path)]
# Document 로드 후 DB에 저장
for i, json_path in enumerate(json_paths) :
loader = JSONLoader(
file_path=json_path,
jq_schema=".[] | .pDate + \" / \" + .title + \" / \" + .description",
text_content=False
)
docs = loader.load()
if i == 0 :
db = Chroma.from_documents(
documents=docs,
embedding=embeddings,
collection_name="2025_news",
persist_directory=DB_PATH
)
db.get()
else :
db.add_documents(
documents=docs,
embedding=embeddings,
collection_name="2025_news",
persist_directory=DB_PATH
)
db.get()
5. Retriever 설정 (DB 저장할 때와 같은 임베딩 메서드 사용하기)
# Retriever
persist_db = Chroma(
persist_directory=DB_PATH,
embedding_function=embeddings,
collection_name="2025_news"
)
retriever = persist_db.as_retriever()
6. 사용할 LLM 모델 설정 및 템플릿 설정
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain.chat_models import init_chat_model
llm = init_chat_model('gpt-4o-mini', model_provider='openai')
def format_docs(docs) :
return "\n\n".join(doc.page_content for doc in docs)
template = """
Question-Answering task Assistant 역할을 맡아주세요. retrieved context를 사용하여 질문에 답변해주세요.
만약에 답을 알지 못한다면, 모른다고 답해주세요.
최대 3문장으로 간결하게 답해주시고, 답변에 사용한 document를 인용해주세요.
질문 : {question}
Context : {context}
Answer :
"""
prompt = ChatPromptTemplate.from_template(template)
rag_chain = (
{"context" : retriever | format_docs, "question" : RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
질문과 답변 예시
DB 저장 시 url이랑 같이 넣어뒀으면 링크 타고 도큐먼트 직접 확인 가능할 듯
일단 처음 RAG 실습해봐서 다음엔 해당 부분 수정
'NLP > 실습' 카테고리의 다른 글
LangChain RAG 실습 2(네이버 뉴스 기사 크롤링) (0) | 2025.06.09 |
---|