실시간 트렌드 키워드를 자동으로 수집하고 싶으신가요? 매번 수동으로 데이터를 복사하는 번거로움을 겪고 계신가요? 이 글에서는 Beautiful Soup을 활용해 여러 사이트의 데이터를 한 번에 리스트로 정리하는 실전 방법을 알려드립니다.
크롤링 데이터를 리스트로 만드는 이유
웹 크롤링으로 수집한 데이터를 리스트 형태로 저장하면 데이터 분석, DB 저장, 엑셀 내보내기 등 다양한 후속 작업이 간편해집니다. 특히 SEO 키워드 분석, 트렌드 모니터링, 경쟁사 분석 등에 활용하면 업무 효율이 3배 이상 향상됩니다.
기본 크롤링 코드 구조 이해하기
필수 라이브러리 설치
from bs4 import BeautifulSoup as bs
import requests
import time
Beautiful Soup은 HTML 파싱에 최적화된 라이브러리이며, requests는 웹 페이지 요청을, time은 서버 부하 방지를 위한 딜레이 설정에 사용됩니다.
전역 리스트 선언
keyword = [] # 수집한 데이터를 저장할 빈 리스트
모든 함수에서 접근 가능한 전역 리스트를 만들어 데이터를 한곳에 모읍니다.
실전 예제: 3개 사이트 동시 크롤링
Keyzard 실시간 키워드 수집
def keyzard():
URL = '<https://keyzard.org/realtimekeyword>'
html = requests.get(URL)
soup = bs(html.text, 'html.parser')
req = soup.select('td.ellipsis100')
for k in req:
keyword.append(k.text.strip()) # strip()으로 공백 제거
핵심 포인트: CSS 선택자 td.ellipsis100을 사용해 정확한 요소만 추출합니다. strip() 메서드로 불필요한 공백을 제거하면 데이터 품질이 향상됩니다.
Google Trends RSS 파싱
def google():
URL = '<https://trends.google.com/trends/trendingsearches/daily/rss?geo=KR>'
html = requests.get(URL)
soup = bs(html.text, 'html.parser')
req = soup.select('item > title')
for i, g in zip(range(21), req):
keyword.append(g.text.strip())
활용 팁: zip() 함수로 상위 21개만 선택해 불필요한 데이터 수집을 방지합니다. RSS 형식은 XML 파서로도 처리 가능하지만, Beautiful Soup이 더 간편합니다.
ZUM 이슈 키워드 추출
def zum():
URL = '<https://issue.zum.com/>'
html = requests.get(URL)
soup = bs(html.text, 'html.parser')
req = soup.select('div.cont > span.word')
for i, z in zip(range(10), req):
keyword.append(z.text.strip())
주의사항: 동적 로딩 사이트는 Selenium이 필요할 수 있습니다. ZUM은 정적 페이지라 requests만으로 충분합니다.
데이터 수집 실행 및 결과 확인
keyzard()
time.sleep(1) # 서버 부담 방지
google()
time.sleep(1)
zum()
print(f"총 {len(keyword)}개 키워드 수집 완료")
print(keyword)
베스트 프랙티스: 각 함수 실행 사이에 1초 딜레이를 넣어 서버에 무리를 주지 않습니다. 일부 사이트는 과도한 요청 시 IP 차단할 수 있습니다.
리스트 데이터 고급 활용법
중복 제거 및 정렬
keyword = list(set(keyword)) # 중복 제거
keyword.sort() # 가나다순 정렬
딕셔너리 리스트로 변환
keyword_dict = []
for idx, kw in enumerate(keyword, 1):
keyword_dict.append({
'rank': idx,
'keyword': kw,
'length': len(kw)
})
구조화된 데이터는 추후 분석이 훨씬 편리합니다.
CSV 파일로 저장
import csv
with open('keywords.csv', 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
writer.writerow(['순위', '키워드'])
for idx, kw in enumerate(keyword, 1):
writer.writerow([idx, kw])
utf-8-sig 인코딩을 사용하면 엑셀에서 한글이 깨지지 않습니다.
에러 처리 및 안정성 강화
Try-Except 구문 추가
def keyzard():
try:
URL = '<https://keyzard.org/realtimekeyword>'
html = requests.get(URL, timeout=10)
soup = bs(html.text, 'html.parser')
req = soup.select('td.ellipsis100')
for k in req:
keyword.append(k.text.strip())
print(f"✅ Keyzard: {len(req)}개 수집 성공")
except requests.exceptions.RequestException as e:
print(f"❌ Keyzard 수집 실패: {e}")
except Exception as e:
print(f"⚠️ 예상치 못한 오류: {e}")
네트워크 오류, 파싱 오류 등 다양한 예외 상황에 대비해야 안정적인 크롤러를 만들 수 있습니다.
User-Agent 헤더 추가
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
html = requests.get(URL, headers=headers, timeout=10)
일부 사이트는 봇 차단을 위해 User-Agent를 확인합니다. 브라우저 헤더를 추가하면 접근 성공률이 높아집니다.
MySQL 데이터베이스 저장하기
import pymysql
def save_to_db(keyword_list):
conn = pymysql.connect(
host='localhost',
user='your_username',
password='your_password',
database='keyword_db',
charset='utf8mb4'
)
cursor = conn.cursor()
for kw in keyword_list:
sql = "INSERT INTO keywords (keyword, collected_at) VALUES (%s, NOW())"
cursor.execute(sql, (kw,))
conn.commit()
cursor.close()
conn.close()
print(f"✅ {len(keyword_list)}개 키워드 DB 저장 완료")
# 실행
save_to_db(keyword)
실시간 데이터를 DB에 축적하면 시계열 분석이 가능해집니다.
성능 최적화 팁
비동기 처리로 속도 향상
import asyncio
import aiohttp
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'<https://keyzard.org/realtimekeyword>',
'<https://trends.google.com/trends/trendingsearches/daily/rss?geo=KR>',
'<https://issue.zum.com/>'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
results = await asyncio.gather(*tasks)
return results
# 실행
results = asyncio.run(main())
비동기 방식을 사용하면 3개 사이트를 동시에 크롤링해 시간을 대폭 단축할 수 있습니다.
자주 발생하는 문제 해결
한글 깨짐 현상
html = requests.get(URL)
html.encoding = 'utf-8' # 인코딩 강제 지정
soup = bs(html.text, 'html.parser')
동적 콘텐츠 크롤링
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get(URL)
time.sleep(3) # 로딩 대기
elements = driver.find_elements(By.CSS_SELECTOR, 'div.keyword')
keywords = [el.text for el in elements]
driver.quit()
JavaScript로 렌더링되는 사이트는 Selenium을 사용해야 합니다.
접속 차단 우회
import random
def get_random_user_agent():
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) Firefox/121.0'
]
return random.choice(user_agents)
headers = {'User-Agent': get_random_user_agent()}
User-Agent를 랜덤하게 변경하면 차단 확률이 낮아집니다.
실무 활용 시나리오
키워드 크롤링 데이터는 SEO 전략 수립, 콘텐츠 기획, 광고 입찰 키워드 선정 등에 활용됩니다. 하루 3회 자동 수집하면 트렌드 변화를 실시간으로 파악할 수 있습니다.
마케팅 대행사에서는 이 데이터를 클라이언트 리포트 자료로 활용하고, 개인 블로거는 인기 키워드로 포스팅 주제를 선정합니다. 데이터 분석가는 시계열 데이터로 트렌드 예측 모델을 만들기도 합니다.
법적 주의사항
웹 크롤링은 각 사이트의 robots.txt 규정을 준수해야 합니다. 과도한 요청은 업무방해죄에 해당할 수 있으며, 개인정보 수집 시 정보통신망법 위반 가능성이 있습니다. 수집한 데이터의 상업적 이용 전 반드시 이용약관을 확인하세요.
마치며
파이썬 크롤링으로 데이터를 리스트화하는 방법을 실전 코드와 함께 살펴봤습니다. 기본 구조를 이해했다면 다양한 사이트에 응용할 수 있습니다. 에러 처리, 성능 최적화, DB 연동까지 적용하면 실무급 크롤러를 만들 수 있습니다.
크롤링 자동화로 시간을 절약하고, 데이터 기반 의사결정의 첫걸음을 시작해보세요.
참고 자료
- Beautiful Soup 공식 문서: https://www.crummy.com/software/BeautifulSoup/bs4/doc/
- Python Requests 라이브러리: https://requests.readthedocs.io/
- 한국저작권위원회 크롤링 가이드: https://www.copyright.or.kr/