1. 학습 목표: 왜 Python과 LLM의 조합인가?
과거의 웹 크롤링은 정규표현식이나 복잡한 CSS 선택자를 활용해 데이터를 파싱해야 했습니다. 하지만 웹사이트의 구조가 조금만 바뀌어도 코드가 깨지는 치명적인 단점이 있었죠. 2026년 현재, 우리는 LLM(대규모 언어 모델)의 추론 능력을 결합하여 어떤 복잡한 웹 페이지에서도 원하는 정보(가격, 날짜, 핵심 요약 등)를 인간처럼 이해하고 추출하는 지능형 스크립트를 제작할 수 있습니다.
이번 강의를 통해 여러분은 파이썬으로 웹 데이터를 수집하고, 이를 LLM에 전달하여 정형화된 JSON 데이터로 변환하는 실무 프로세스를 완벽히 습득하게 됩니다. 이 기술은 시장 조사, 뉴스 모니터링, 경쟁사 분석 등 다양한 비즈니스 영역에서 즉시 활용 가능합니다.
2. 사전 준비 사항
실습을 시작하기 전에 아래의 환경이 갖춰져 있는지 확인해 주세요. 본 강의는 최신 안정화 버전인 Python 3.11 이상 환경을 기준으로 진행됩니다.
- 운영체제(OS): Windows 11, macOS Sequoia, 또는 Ubuntu 24.04 이상
- 개발 도구: Visual Studio Code (VS Code) 권장
- 언어 버전: Python 3.11.x 또는 3.12.x
- 필수 라이브러리 설치: 터미널(Terminal)에서 아래 명령어를 입력하여 필요한 패키지를 설치합니다.
pip install requests beautifulsoup4 openai python-dotenv
- API 키 준비: OpenAI API 키(또는 호환 가능한 LLM 서비스 키)가 필요합니다. 프로젝트 루트 폴더에
.env파일을 생성하고OPENAI_API_KEY=your_key_here형태로 저장해 두세요.
3. 단계별 실습 과정
1단계: 웹 페이지 원본 데이터(HTML) 가져오기
가장 먼저 타겟 웹사이트의 HTML 소스를 가져와야 합니다. requests 라이브러리를 사용하여 웹 서버에 요청을 보내고 응답을 받습니다. 이때 웹 브라우저처럼 보이기 위해 User-Agent 헤더를 추가하는 것이 중요합니다.
import requests
from bs4 import BeautifulSoup
def get_web_content(url):
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
else:
print(f"Error: {response.status_code}")
return None
2단계: 불필요한 태그 제거 및 텍스트 정제
HTML에는 자바스크립트(script), 스타일시트(style) 등 정보 추출에 방해가 되는 요소가 많습니다. LLM의 토큰(Token) 비용을 절약하고 정확도를 높이기 위해 핵심 텍스트만 남기는 전처리 과정이 필수적입니다.
def clean_html(html_content):
soup = BeautifulSoup(html_content, 'html.parser')
# 불필요한 태그 제거
for script_or_style in soup(["script", "style", "header", "footer", "nav"]):
script_or_style.decompose()
# 텍스트 추출 및 공백 정리
text = soup.get_text()
lines = (line.strip() for line in text.splitlines())
chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
return "\n".join(chunk for chunk in chunks if chunk)
3단계: LLM을 활용한 핵심 정보 추출 로직 구현
이제 정제된 텍스트를 LLM에 전달합니다. 핵심은 ‘프롬프트 엔지니어링’입니다. LLM에게 어떤 정보를 어떤 형식(JSON)으로 추출할지 명확하게 지시해야 합니다.
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def extract_info_with_llm(cleaned_text):
prompt = f"""
다음 웹사이트 텍스트 내용에서 주요 정보를 추출하여 JSON 형식으로 출력해줘.
반드시 다음 필드를 포함해야 해:
1. title (페이지 제목)
2. main_topic (핵심 주제 1문장)
3. key_points (주요 내용 리스트)
4. contact_info (연락처 또는 이메일, 없으면 null)
텍스트 내용:
{cleaned_text[:4000]}
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
response_format={ "type": "json_object" }
)
return response.choices[0].message.content
4. 전체 통합 코드 및 실행
위의 단계들을 하나로 합쳐 실제 작동하는 스크립트를 완성합니다. 이 스크립트는 URL을 입력받아 최종적으로 구조화된 데이터를 출력합니다.
def main():
target_url = "https://example.com/news/article-123" # 실습 시 실제 URL로 변경
print("데이터 수집 중...")
raw_html = get_web_content(target_url)
if raw_html:
print("데이터 정제 및 LLM 분석 중...")
clean_text = clean_html(raw_html)
result_json = extract_info_with_llm(clean_text)
print("\n=== 추출된 핵심 정보 ===")
print(result_json)
if __name__ == "__main__":
main()
5. 결과 확인 및 실무 활용 팁
스크립트를 실행하면 복잡한 HTML 문서가 깔끔한 JSON 데이터로 변환된 것을 확인할 수 있습니다. 실무에서 이 기술을 더욱 고도화하기 위한 세 가지 팁을 드립니다.
1) 토큰 제한 관리
웹 페이지의 내용이 너무 길 경우 LLM의 컨텍스트 창(Context Window)을 초과할 수 있습니다. 이럴 때는 페이지를 섹션별로 나누어 분석하거나, 텍스트 요약 알고리즘을 먼저 적용한 뒤 LLM에 전달하는 전략이 필요합니다.
2) 동적 로딩 페이지 처리
만약 requests로 가져온 HTML에 데이터가 없다면, 해당 사이트는 자바스크립트로 데이터를 나중에 불러오는(CSR) 방식일 확률이 높습니다. 이 경우 Playwright나 Selenium 같은 브라우저 자동화 도구를 병행 사용해야 합니다.
3) 데이터 검증(Validation)
LLM은 가끔 환각(Hallucination) 현상을 일으킬 수 있습니다. 추출된 데이터가 특정 형식을 따르는지 Pydantic 라이브러리 등을 활용해 유효성 검사를 수행하면 더욱 신뢰도 높은 자동화 시스템을 구축할 수 있습니다.
이제 여러분은 단순한 크롤링을 넘어, AI를 활용한 지능형 데이터 엔지니어링의 첫걸음을 떼었습니다. 이 코드를 바탕으로 여러분만의 뉴스 레터 요약기나 가격 비교 봇을 만들어 보시기 바랍니다.