LangChain과 대형 언어 모델(LLM)을 이용한 웹 스크래핑 방법 포함!
소개
웹 스크래핑은 웹사이트에서 데이터를 추출하는 기술로, 데이터 수집과 분석을 자동화할 수 있는 강력한 도구입니다. 현대의 데이터 중심 사회에서 웹 스크래핑은 비즈니스, 연구, 개발 등의 다양한 분야에서 널리 사용되고 있습니다. 예를 들어, 경쟁사 분석을 위해 가격 정보를 수집하거나, 시장 동향을 파악하기 위해 소셜 미디어 데이터를 수집하는 등의 용도로 활용됩니다. 이처럼 웹 스크래핑은 수작업으로는 불가능한 대규모 데이터 수집을 가능하게 하여, 시간과 비용을 절감하고, 정확한 데이터 기반 의사 결정을 지원합니다.
웹 스크래핑을 효과적으로 수행하려면 다양한 기술과 도구를 이해하고 사용할 수 있어야 합니다. 간단한 HTML 파싱부터 복잡한 동적 웹 페이지의 데이터 추출, 그리고 최신의 대형 언어 모델(LLM)을 활용한 방법까지, 각각의 방법은 고유한 장점과 사용 사례를 가지고 있습니다. 이번 글에서는 웹 스크래핑의 기초를 시작으로, 다섯 가지 주요 웹 스크래핑 방법을 소개합니다. 특히, 최신 기술인 LangChain과 LLM을 활용한 웹 스크래핑 방법에 대해 자세히 다루어, 독자들이 최신 웹 스크래핑 기술을 이해하고 적용할 수 있도록 돕고자 합니다.
I. 기본 HTML 이해하기
웹 스크래핑을 시작하기 전에 HTML의 기본 구조를 이해하는 것이 중요합니다. HTML(하이퍼텍스트 마크업 언어)은 웹 페이지를 구성하는 기본 언어로, 태그와 속성으로 구성됩니다. 웹 페이지의 콘텐츠는 HTML 태그 안에 포함되며, 이러한 태그는 웹 페이지의 구조를 정의합니다. 웹 스크래핑을 통해 데이터를 추출하려면 이러한 태그와 속성을 잘 이해하고, 원하는 데이터를 정확히 찾아낼 수 있어야 합니다.
HTML 문서는 계층 구조로 되어 있으며, 각 요소는 다른 요소를 포함하거나 포함될 수 있습니다. 예를 들어, <html>
태그는 전체 HTML 문서를 감싸고, 그 안에는 <head>
와 <body>
태그가 있습니다. <body>
태그 안에는 다양한 콘텐츠 태그가 포함되며, 각 태그는 고유한 역할을 합니다. 예를 들어, <h1>
태그는 주요 제목을 나타내고, <p>
태그는 단락을 나타내며, <a>
태그는 하이퍼링크를 나타냅니다.
웹 스크래핑을 할 때는 특정 태그를 찾고 그 안에 포함된 데이터를 추출하는 것이 일반적입니다. 이를 위해 태그의 이름, 클래스, ID 등을 활용하여 특정 요소를 선택할 수 있습니다. 예를 들어, BeautifulSoup을 사용하면 .find()
메서드를 통해 특정 태그를 찾고, .find_all()
메서드를 통해 여러 태그를 찾을 수 있습니다. 이러한 메서드는 태그의 이름, 클래스, ID 등을 기준으로 요소를 선택할 수 있게 해줍니다.
또한, HTML 문서에는 종종 자바스크립트로 동적으로 생성되는 콘텐츠가 포함됩니다. 이러한 경우에는 기본적인 HTML 파싱만으로는 데이터를 추출할 수 없으며, 자바스크립트 실행을 지원하는 도구가 필요합니다. Selenium과 같은 도구는 실제 브라우저를 자동으로 제어하여 동적으로 생성된 콘텐츠를 포함한 모든 요소를 추출할 수 있습니다.
웹 스크래핑을 효과적으로 수행하기 위해서는 HTML 구조를 이해하는 것뿐만 아니라, 다양한 웹 페이지의 특성과 이를 처리하기 위한 도구와 기술을 잘 활용하는 것이 중요합니다. 이를 통해 원하는 데이터를 정확하고 효율적으로 추출할 수 있습니다.
II. 웹 스크래핑 방법
방법 1: BeautifulSoup과 Requests 사용하기
BeautifulSoup과 Requests는 파이썬에서 가장 많이 사용되는 웹 스크래핑 라이브러리입니다. Requests는 웹 페이지를 요청하고 응답을 받는 역할을 하며, BeautifulSoup은 HTML이나 XML 문서를 파싱하여 원하는 데이터를 추출하는 데 사용됩니다.
import requests
from bs4 import BeautifulSoup
url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
title = soup.find("h1").text
print(title)
방법 2: Scrapy 사용하기
Scrapy는 웹 스크래핑을 위한 강력한 프레임워크로, 대규모 데이터 수집에 최적화되어 있습니다. Scrapy를 사용하면 크롤러를 정의하고, 여러 페이지에서 데이터를 효율적으로 수집할 수 있습니다.
import scrapy
class ExampleSpider(scrapy.Spider):
name = "example"
start_urls = ["https://example.com"]
def parse(self, response):
title = response.xpath("//h1/text()").get()
print(title)
방법 3: Selenium
Selenium은 웹 브라우저를 자동화하기 위한 도구로, 웹 애플리케이션을 테스트하거나 동적으로 생성된 웹 페이지의 콘텐츠를 스크래핑하는 데 유용합니다. Selenium은 다양한 웹 브라우저를 제어할 수 있으며, 자바스크립트로 동적으로 생성된 콘텐츠를 포함한 모든 요소를 추출할 수 있습니다. 이를 통해 단순한 HTML 파싱만으로는 접근할 수 없는 데이터도 수집할 수 있습니다.
Selenium 설치 및 설정
Selenium을 사용하려면 먼저 라이브러리를 설치해야 합니다. 다음 명령어를 사용하여 Selenium을 설치할 수 있습니다.
pip install selenium
또한, 사용하려는 웹 브라우저의 드라이버도 설치해야 합니다. 예를 들어, 크롬 브라우저를 사용할 경우 ChromeDriver를 다운로드하여 설치해야 합니다.
기본 사용법
Selenium을 사용하여 웹 페이지를 제어하고 데이터를 추출하는 기본 예제는 다음과 같습니다.
from selenium import webdriver
# Chrome 드라이버 경로를 설정하고 브라우저를 시작합니다.
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
driver.get("https://example.com")
# 특정 요소를 찾고 텍스트를 추출합니다.
title = driver.find_element_by_tag_name("h1").text
print(title)
# 브라우저를 닫습니다.
driver.quit()
이 예제에서는 Chrome 브라우저를 사용하여 https://example.com
페이지를 열고, <h1>
태그를 찾아 그 텍스트를 출력합니다.
동적 콘텐츠 처리
동적 콘텐츠를 처리할 때는 자바스크립트가 완료될 때까지 기다려야 합니다. Selenium은 WebDriverWait
와 expected_conditions
모듈을 사용하여 조건이 충족될 때까지 기다릴 수 있습니다.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
driver.get("https://example.com")
# 특정 요소가 로드될 때까지 기다립니다.
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h1"))
)
# 텍스트를 추출합니다.
title = element.text
print(title)
driver.quit()
이 예제에서는 <h1>
태그가 로드될 때까지 최대 10초 동안 기다린 후, 해당 요소의 텍스트를 추출합니다.
양식 제출 및 상호작용
Selenium을 사용하면 웹 페이지의 양식을 자동으로 작성하고 제출할 수도 있습니다.
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
driver.get("https://example.com/login")
# 사용자 이름과 비밀번호를 입력하고 로그인 버튼을 클릭합니다.
username = driver.find_element_by_name("username")
password = driver.find_element_by_name("password")
login_button = driver.find_element_by_xpath("//input[@type='submit']")
username.send_keys("your_username")
password.send_keys("your_password")
login_button.click()
# 로그인 후 페이지에서 데이터를 추출합니다.
profile_name = driver.find_element_by_id("profile-name").text
print(profile_name)
driver.quit()
이 예제에서는 로그인 페이지에서 사용자 이름과 비밀번호를 입력하고 로그인 버튼을 클릭한 후, 로그인된 페이지에서 프로필 이름을 추출합니다.
Selenium은 이처럼 다양한 상호작용과 동적 콘텐츠 처리가 필요한 경우 매우 유용한 도구입니다. 웹 페이지의 모든 요소를 제어하고 데이터를 추출할 수 있는 강력한 기능을 제공하여, 복잡한 웹 스크래핑 작업을 간단하게 처리할 수 있습니다.
방법 4: Requests와 lxml
Requests와 lxml을 조합하여 웹 스크래핑을 수행하는 방법은 매우 효율적이며 강력합니다. Requests는 HTTP 요청을 쉽게 보낼 수 있는 라이브러리이며, lxml은 HTML과 XML 문서를 빠르고 유연하게 파싱할 수 있는 라이브러리입니다. 이 두 라이브러리를 함께 사용하면 웹 페이지에서 원하는 데이터를 효율적으로 추출할 수 있습니다.
Requests 설치 및 기본 사용법
Requests는 간단하고 직관적인 API를 제공하여 웹 페이지에 대한 HTTP 요청을 쉽게 보낼 수 있습니다. Requests를 설치하려면 다음 명령어를 사용합니다:
pip install requests
기본적인 사용 예시는 다음과 같습니다:
import requests
url = "https://example.com"
response = requests.get(url)
# 응답의 상태 코드 확인
print(response.status_code)
# 페이지 콘텐츠 출력
print(response.text)
lxml 설치 및 기본 사용법
lxml은 HTML과 XML 문서를 파싱하고, XPath를 사용하여 특정 요소를 추출할 수 있는 강력한 라이브러리입니다. lxml을 설치하려면 다음 명령어를 사용합니다:
pip install lxml
기본적인 사용 예시는 다음과 같습니다:
from lxml import html
# HTML 문자열을 파싱
tree = html.fromstring('<html><body><h1>Hello, world!</h1></body></html>')
# XPath를 사용하여 <h1> 태그의 텍스트 추출
title = tree.xpath('//h1/text()')[0]
print(title)
Requests와 lxml을 조합한 웹 스크래핑
Requests와 lxml을 함께 사용하면 웹 페이지에서 데이터를 효율적으로 추출할 수 있습니다. 다음은 Requests와 lxml을 사용하여 웹 페이지에서 특정 데이터를 추출하는 예제입니다:
import requests
from lxml import html
# 웹 페이지 요청
url = "https://example.com"
response = requests.get(url)
# HTML 파싱
tree = html.fromstring(response.content)
# XPath를 사용하여 원하는 데이터 추출
title = tree.xpath('//h1/text()')[0]
print(title)
이 예제에서는 https://example.com
웹 페이지를 요청하고, 응답 내용을 lxml을 사용하여 파싱한 후, XPath를 사용하여 <h1>
태그의 텍스트를 추출합니다.
고급 사용법: 여러 요소 추출
lxml을 사용하면 여러 요소를 한 번에 추출할 수도 있습니다. 예를 들어, 웹 페이지에서 모든 링크와 그 텍스트를 추출하려면 다음과 같이 할 수 있습니다:
import requests
from lxml import html
# 웹 페이지 요청
url = "https://example.com"
response = requests.get(url)
# HTML 파싱
tree = html.fromstring(response.content)
# XPath를 사용하여 모든 링크와 그 텍스트 추출
links = tree.xpath('//a')
for link in links:
href = link.get('href')
text = link.text_content()
print(f"Link: {href}, Text: {text}")
이 예제에서는 모든 <a>
태그를 찾아 각 링크의 URL(href
속성)과 텍스트를 추출합니다.
예외 처리 및 리소스 관리
Requests와 lxml을 사용할 때는 예외 처리를 통해 에러에 대응하고, 리소스를 효율적으로 관리하는 것이 중요합니다. 다음은 예외 처리를 추가한 예제입니다:
import requests
from lxml import html
url = "https://example.com"
try:
response = requests.get(url)
response.raise_for_status() # HTTP 에러가 발생하면 예외 발생
tree = html.fromstring(response.content)
title = tree.xpath('//h1/text()')[0]
print(title)
except requests.exceptions.RequestException as e:
print(f"HTTP 요청 중 오류 발생: {e}")
except IndexError:
print("요소를 찾을 수 없습니다.")
except Exception as e:
print(f"기타 오류 발생: {e}")
이 예제에서는 HTTP 요청 중 발생할 수 있는 다양한 예외를 처리하여 프로그램의 안정성을 높입니다.
Requests와 lxml은 간단한 HTML 파싱부터 복잡한 데이터 추출까지 다양한 작업을 수행할 수 있는 강력한 도구입니다. 이들을 활용하여 효율적이고 안정적인 웹 스크래핑을 구현할 수 있습니다.
방법 5: LangChain을 사용한 웹 스크래핑 개요
LangChain은 다양한 자연어 처리(NLP) 작업을 지원하는 프레임워크로, 대형 언어 모델(LLM)을 활용하여 웹 스크래핑 작업을 더욱 효율적이고 정교하게 수행할 수 있습니다. LangChain을 사용하면 단순한 HTML 파싱을 넘어 복잡한 텍스트 추출 및 데이터 구조화 작업을 자동화할 수 있습니다. 다음은 LangChain을 사용한 웹 스크래핑의 주요 개요입니다.
1. LangChain 설치 및 설정
LangChain을 사용하려면 먼저 필요한 라이브러리들을 설치해야 합니다. 일반적으로 langchain
, requests
, beautifulsoup4
, lxml
, 그리고 comet_llm
등의 패키지를 사용합니다. pip
명령어를 통해 설치할 수 있습니다.
pip install langchain requests beautifulsoup4 lxml comet_llm
2. 환경 변수 설정
OpenAI API 키와 Comet API 키를 환경 변수로 설정하여 프로젝트에서 사용할 수 있도록 합니다. .env
파일을 사용하여 환경 변수를 로드할 수 있습니다.
import os
import dotenv
# .env 파일에서 환경 변수를 불러옵니다.
dotenv.load_dotenv()
# 환경 변수에서 OpenAI와 Comet 키를 가져옵니다.
MY_OPENAI_KEY = os.getenv("MY_OPENAI_KEY")
MY_COMET_KEY = os.getenv("MY_COMET_KEY")
3. LangChain 초기화 및 HTML 로딩
LangChain의 다양한 모듈을 사용하여 HTML 콘텐츠를 로드하고 파싱합니다. AsyncChromiumLoader
를 사용하여 비동기 방식으로 웹 페이지의 HTML 콘텐츠를 로드할 수 있습니다.
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import AsyncChromiumLoader
# OpenAI API 키로 ChatOpenAI 인스턴스를 초기화합니다.
llm = ChatOpenAI(openai_api_key=MY_OPENAI_KEY)
# AsyncChromiumLoader를 사용하여 HTML 콘텐츠를 로드합니다.
url = "https://www.imdb.com/list/ls566941243/"
loader = AsyncChromiumLoader([url])
docs = loader.load()
4. HTML 콘텐츠 변환 및 데이터 추출
BeautifulSoupTransformer를 사용하여 필요한 HTML 태그를 추출하고, RecursiveCharacterTextSplitter를 사용하여 문서를 분할합니다. 이러한 과정을 통해 필요한 데이터를 구조화합니다.
from langchain_community.document_transformers import BeautifulSoupTransformer
from langchain.text_splitter import RecursiveCharacterTextSplitter
# BeautifulSoupTransformer를 사용하여 필요한 태그를 추출합니다.
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(
docs, tags_to_extract=["h3", "p"]
)
# RecursiveCharacterTextSplitter를 사용하여 변환된 문서를 분할합니다.
splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
splits = splitter.split_documents(docs_transformed)
5. LLM을 통한 데이터 추출 및 검증
LangChain의 create_extraction_chain
을 사용하여 정의된 JSON 스키마에 따라 데이터를 추출하고 검증합니다. 이 과정에서 추출된 데이터는 Comet에 로그로 기록됩니다.
from langchain.chains import create_extraction_chain
# JSON 스키마 정의 (영화 데이터 검증용)
schema = {
"properties": {
"movie_title": {"type": "string"},
"stars": {"type": "integer"},
"genre": {"type": "array", "items": {"type": "string"}},
"runtime": {"type": "string"},
"rating": {"type": "string"},
},
"required": ["movie_title", "stars", "genre", "runtime", "rating"],
}
def extract_movie_data(content: str, schema: dict):
"""
JSON 스키마를 사용하여 콘텐츠에서 영화 데이터를 추출합니다.
매개변수:
- content (str): 영화 데이터를 포함하는 텍스트 콘텐츠.
- schema (dict): 영화 데이터를 검증하기 위한 JSON 스키마.
반환값:
- dict: 추출된 영화 데이터.
"""
start_time = time.time()
extracted_content = create_extraction_chain(schema=schema, llm=llm).run(content)
end_time = time.time()
# Comet 프로젝트에 메타데이터와 출력을 기록하여 추적합니다.
comet_llm.log_prompt(
prompt=str(content),
metadata={
"schema": schema
},
output=extracted_content,
duration=end_time - start_time,
)
return extracted_content
# 첫 번째 분할 페이지 콘텐츠를 사용하여 영화 데이터를 추출합니다.
extracted_content = extract_movie_data(schema=schema, content=splits[0].page_content)
# 추출된 영화 데이터를 출력합니다.
print(extracted_content)
결론
LangChain을 사용한 웹 스크래핑은 단순한 HTML 파싱을 넘어서, LLM을 활용하여 복잡한 데이터 추출 및 구조화 작업을 자동화할 수 있는 강력한 방법입니다. 이를 통해 다양한 웹 페이지에서 효율적으로 데이터를 수집하고, 정교하게 처리할 수 있습니다.
방법 5: LangChain을 사용한 웹 스크래핑
LangChain은 다양한 자연어 처리(NLP) 작업을 지원하는 프레임워크로, 대형 언어 모델(LLM)을 활용하여 웹 스크래핑 작업을 더욱 효율적이고 정교하게 수행할 수 있습니다. LangChain을 사용하면 단순한 HTML 파싱을 넘어 복잡한 텍스트 추출 및 데이터 구조화 작업을 자동화할 수 있습니다.
import os
import dotenv
import time
# .env 파일에서 환경 변수를 불러옵니다.
dotenv.load_dotenv()
# 환경 변수에서 OpenAI와 Comet 키를 가져옵니다.
MY_OPENAI_KEY = os.getenv("MY_OPENAI_KEY")
MY_COMET_KEY = os.getenv("MY_COMET_KEY")
# LLM 프로젝트에서, Comet 프로젝트에 출력을 기록합니다.
# 이 데모에서는 단 하나의 URL만 사용합니다. 하지만 여러 URL을 반복 처리해야 하는 경우,
# Comet LLM의 실험 추적 기능이 매우 유용합니다.
import comet_llm
# Comet 프로젝트를 초기화합니다.
comet_llm.init(
project="langchain-web-scraping",
api_key=MY_COMET_KEY,
)
# nest_asyncio를 적용하여 비동기 문제를 해결합니다.
import nest_asyncio
nest_asyncio.apply()
# langchain에서 필요한 모듈을 가져옵니다.
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import AsyncChromiumLoader
from langchain_community.document_transformers import BeautifulSoupTransformer
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import create_extraction_chain
# URL을 정의합니다.
url = "https://www.imdb.com/list/ls566941243/"
# OpenAI API 키로 ChatOpenAI 인스턴스를 초기화합니다.
llm = ChatOpenAI(openai_api_key=MY_OPENAI_KEY)
# AsyncChromiumLoader를 사용하여 HTML 콘텐츠를 로드합니다.
loader = AsyncChromiumLoader([url])
docs = loader.load()
# 참조용으로 HTML 콘텐츠를 텍스트 파일에 저장합니다.
with open("imdb_langchain_html.txt", "w", encoding="utf-8") as file:
file.write(str(docs[0].page_content))
print("페이지 콘텐츠가 imdb_langchain_html.txt에 저장되었습니다.")
# BeautifulSoupTransformer를 사용하여 로드된 HTML을 변환합니다.
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(
docs, tags_to_extract=["h3", "p"]
)
# RecursiveCharacterTextSplitter를 사용하여 변환된 문서를 분할합니다.
splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
splits = splitter.split_documents(docs_transformed)
이미지를 참고하여 필요한 데이터를 추출하기 위해 HTML 레이아웃을 탐색하는 방법을 설명하겠습니다. 이 예제에서는 영화 제목, 장르, 평점, 상영 시간을 추출하기 위해 <h3>
및 <p>
태그를 사용할 것입니다.
이미지 설명
이미지에는 영화 “Bullet Train”의 정보가 포함된 IMDb 페이지의 HTML 소스 코드가 나와 있습니다. 주요 요소는 다음과 같습니다:
<h3>
태그: 영화 제목이 포함됨<p>
태그: 장르, 평점, 상영 시간 등이 포함됨
import comet_llm
# Comet 프로젝트를 초기화합니다.
comet_llm.init(
project="langchain-web-scraping",
api_key=MY_COMET_KEY,
)
# nest_asyncio를 적용하여 비동기 문제를 해결합니다.
import nest_asyncio
nest_asyncio.apply()
# langchain에서 필요한 모듈을 가져옵니다.
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import AsyncChromiumLoader
from langchain_community.document_transformers import BeautifulSoupTransformer
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import create_extraction_chain
# URL을 정의합니다.
url = "https://www.imdb.com/list/ls566941243/"
# OpenAI API 키로 ChatOpenAI 인스턴스를 초기화합니다.
llm = ChatOpenAI(openai_api_key=MY_OPENAI_KEY)
# AsyncChromiumLoader를 사용하여 HTML 콘텐츠를 로드합니다.
loader = AsyncChromiumLoader([url])
docs = loader.load()
# 참조용으로 HTML 콘텐츠를 텍스트 파일에 저장합니다.
with open("imdb_langchain_html.txt", "w", encoding="utf-8") as file:
file.write(str(docs[0].page_content))
print("페이지 콘텐츠가 imdb_langchain_html.txt에 저장되었습니다.")
# BeautifulSoupTransformer를 사용하여 로드된 HTML을 변환합니다.
# 필요한 태그를 추출하기 위해 'h3'와 'p' 태그를 사용합니다.
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(
docs, tags_to_extract=["h3", "p"]
)
# RecursiveCharacterTextSplitter를 사용하여 변환된 문서를 분할합니다.
splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
splits = splitter.split_documents(docs_transformed)
# JSON 스키마 정의 (영화 데이터 검증용)
schema = {
"properties": {
"movie_title": {"type": "string"},
"stars": {"type": "integer"},
"genre": {"type": "array", "items": {"type": "string"}},
"runtime": {"type": "string"},
"rating": {"type": "string"},
},
"required": ["movie_title", "stars", "genre", "runtime", "rating"],
}
def extract_movie_data(content: str, schema: dict):
"""
JSON 스키마를 사용하여 콘텐츠에서 영화 데이터를 추출합니다.
매개변수:
- content (str): 영화 데이터를 포함하는 텍스트 콘텐츠.
- schema (dict): 영화 데이터를 검증하기 위한 JSON 스키마.
반환값:
- dict: 추출된 영화 데이터.
"""
# 제공된 스키마와 콘텐츠로 추출 체인을 실행합니다.
start_time = time.time()
extracted_content = create_extraction_chain(schema=schema, llm=llm).run(content)
end_time = time.time()
# Comet 프로젝트에 메타데이터와 출력을 기록하여 추적합니다.
comet_llm.log_prompt(
prompt=str(content),
metadata={
"schema": schema
},
output=extracted_content,
duration=end_time - start_time,
)
return extracted_content
# 첫 번째 분할 페이지 콘텐츠를 사용하여 영화 데이터를 추출합니다.
extracted_content = extract_movie_data(schema=schema, content=splits[0].page_content)
# 추출된 영화 데이터를 출력합니다.
print(extracted_content)
각 코드 라인에 대한 설명
import comet_llm
: Comet LLM 라이브러리를 임포트합니다.comet_llm.init(...)
: Comet 프로젝트를 초기화합니다.import nest_asyncio
: nest_asyncio를 임포트합니다.nest_asyncio.apply()
: 비동기 문제를 해결하기 위해 적용합니다.- 필요한
langchain
모듈을 임포트합니다. - IMDb URL을 정의합니다.
ChatOpenAI
인스턴스를 OpenAI API 키로 초기화합니다.AsyncChromiumLoader
를 사용하여 HTML 콘텐츠를 로드합니다.- HTML 콘텐츠를 텍스트 파일에 저장합니다.
BeautifulSoupTransformer
를 사용하여 필요한 태그(h3
와p
)를 추출합니다.RecursiveCharacterTextSplitter
를 사용하여 변환된 문서를 분할합니다.- 영화 데이터를 검증하기 위한 JSON 스키마를 정의합니다.
extract_movie_data
함수를 정의하여 JSON 스키마를 사용하여 영화 데이터를 추출합니다.- 첫 번째 분할 페이지 콘텐츠에서
extract_movie_data
함수를 사용하여 영화 데이터를 추출합니다. - 추출된 영화 데이터를 출력합니다.
BeautifulSoupTransformer를 사용하여 필요한 태그(h3와 p)를 추출하는 이유는 다음과 같습니다:
- 필요한 데이터 필터링: IMDb 페이지에서 영화와 관련된 중요한 정보는 특정 태그 안에 있습니다. 예를 들어, 영화 제목은
<h3>
태그 안에, 영화의 장르, 평점, 상영 시간 등의 정보는<p>
태그 안에 있습니다. 따라서 이러한 특정 태그를 추출함으로써 필요한 데이터만 필터링할 수 있습니다. - 데이터 정리: 웹 페이지에는 많은 불필요한 데이터와 요소들이 포함되어 있습니다. 이러한 데이터를 모두 파싱하면 처리해야 할 데이터의 양이 많아지고, 원하는 정보를 찾기 어려워질 수 있습니다. 특정 태그만 추출하면 데이터의 양을 줄이고, 필요한 정보만 효율적으로 추출할 수 있습니다.
- 데이터 정확성 향상: 특정 태그를 추출하면 데이터의 정확성을 높일 수 있습니다. 예를 들어, 영화 제목이나 평점과 같이 특정 태그에 포함된 정보를 정확하게 추출함으로써 데이터의 일관성을 유지할 수 있습니다.
- 후속 처리 용이성: 추출된 특정 태그의 데이터를 후속 처리(예: 텍스트 분할, LLM을 통한 정보 추출 등)하기가 더 쉽습니다. 특정 태그를 추출하면 이러한 태그에 포함된 정보만을 대상으로 작업을 수행할 수 있어 처리 과정이 간단해집니다.
결론
웹 스크래핑은 데이터 수집과 분석에 필수적인 기술입니다. 이 글에서는 5가지 웹 스크래핑 방법에 대해 알아보았습니다. 각 방법의 특징과 장단점을 이해하고, 프로젝트의 요구사항에 맞는 방법을 선택하는 것이 중요합니다. 또한, LangChain과 같은 LLM 기반 도구를 활용하면 더욱 발전된 웹 스크래핑이 가능할 것입니다.