0. 이 글은 누구를 위한 글인가요?
- 인터넷에서 표, 제목, 가격 등 정보를 자동으로 수집하고 싶어요!
- BeautifulSoup? 뭔지 모르겠어요. 처음부터 알려주세요.
- Python으로 뉴스 제목이나 날씨 정보를 가져오고 싶어요.
가장 쉬운 예제로 웹에서 데이터를 추출하는 법을 알려드립니다.
1. 웹 크롤링이란?
- 웹사이트의 HTML 구조를 분석해 원하는 데이터를 자동 수집하는 작업입니다.
- BeautifulSoup + requests 조합으로 가장 많이 사용됩니다.
- 뉴스 제목, 쇼핑몰 가격, 리뷰 등 다양한 정보 수집 가능!
2. 필요한 도구 설치
pip install requests beautifulsoup4
라이브러리 | 설명 |
---|---|
requests | 웹사이트 HTML 요청/다운로드 |
beautifulsoup4 | HTML 파싱 및 원하는 태그 찾기 |
3. 예제 웹페이지: 네이버 뉴스 메인
- URL: https://news.naver.com
- 목표: 메인 뉴스 헤드라인 제목만 수집하기
4. HTML 구조 파악 방법
- 크롬 브라우저에서 네이버 뉴스 접속
- 뉴스 제목에 마우스 올린 후 오른쪽 클릭 → 검사
- <a> 태그 또는 <div class="cjs_t"> 등 구조 확인
5. 기본 코드 - 모든 텍스트 수집
import requests
from bs4 import BeautifulSoup
url = "https://news.naver.com/"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
a_tags = soup.find_all('a')
for tag in a_tags:
title = tag.get_text().strip()
if title:
print(title)
출력 예시
네이버
뉴스
스포츠
연예
경제
오늘의 주요 뉴스
...
→ 너무 많아서 특정 영역만 필터링할 필요가 있어요.
6. 뉴스 헤드라인만 추출하기 (div + class 기반)
# 모든 뉴스 블록 찾기
news_blocks = soup.find_all('div', class_='comp_news_feed')
# 결과 담을 리스트
news_titles = []
# 각 뉴스 블록에서 제목 추출
for block in news_blocks:
# 메인 뉴스 제목
main_title_tag = block.find('strong', class_='cnf_news_title')
if main_title_tag:
main_title = main_title_tag.get_text(strip=True)
news_titles.append(main_title)
# 하위 뉴스 제목들
sub_title_tags = block.find_all('a', class_='cnf_news')
for tag in sub_title_tags:
sub_title = tag.get_text(strip=True)
news_titles.append(sub_title)
# 출력
for idx, title in enumerate(news_titles, 1):
print(f"{idx}. {title}")
출력 예시
1. 선관위가 편향? 尹후보 향한 비방·허위사실 삭제 가장 많았다
2. 계엄 100일, "尹의 정치적 자해"라던 조선일보 어떻게 변했나
3. 고전IP, 어디까지 바꿔도 될까…'백설공주' 실사판이 던진 질문
4. 귀여운 멸종위기종? 그 뒤엔 생태계 붕괴 있다
5. '정치 격랑'의 3월 마지막주, 의대생 복귀 데드라인
6. NASA, 여성·유색인종 달착륙 계획 철회
7. '잡아 먹거나, 잡아 먹히거나'…사냥꾼 거미, 사냥감 거미
8. 법 시행 날개 단 '재생의료'…'제2의 인보사 사태' 막아야
9. 중대본 "동시 산불로 산림 3,286㏊ 소실"…10명 사상
10. 美 그랜드캐니언 여행 한국인 여성 3명, 실종 10일째
7. 크롤링한 뉴스 → 표로 정리하기 (DataFrame)
import pandas as pd
# 뉴스 저장 리스트
news_list = []
# 블록 순회하며 제목 + 링크 추출
for block in news_blocks:
# 메인 뉴스
main_tag = block.find('a', class_='cnf_news_area')
main_title_tag = block.find('strong', class_='cnf_news_title')
if main_tag and main_title_tag:
main_title = main_title_tag.get_text(strip=True)
main_link = main_tag['href']
news_list.append({'제목': main_title, '링크': main_link})
# 하위 뉴스들
sub_tags = block.find_all('a', class_='cnf_news')
for tag in sub_tags:
sub_title = tag.get_text(strip=True)
sub_link = tag['href']
news_list.append({'제목': sub_title, '링크': sub_link})
# DataFrame으로 정리
df = pd.DataFrame(news_list)
print(df.head())
출력 예시
제목 링크
0 선관위가 편향? 尹후보 향한 비방·허위사실 삭제 가장 많았다 https://n.news.naver.com/article/006/0000129114
1 계엄 100일, "尹의 정치적 자해"라던 조선일보 어떻게 변했나 https://n.news.naver.com/article/006/0000129112
2 고전IP, 어디까지 바꿔도 될까…'백설공주' 실사판이 던진 질문 https://n.news.naver.com/article/006/0000129113
3 귀여운 멸종위기종? 그 뒤엔 생태계 붕괴 있다 https://n.news.naver.com/article/006/0000129111
4 '정치 격랑'의 3월 마지막주, 의대생 복귀 데드라인 https://n.news.naver.com/article/584/0000031514
8. 결과 저장 (CSV)
df.to_csv('네이버_뉴스_헤드라인.csv', index=False, encoding='utf-8-sig')
→ Excel에서도 한글 안 깨지고 열 수 있어요!
9. 마무리 요약
단계 | 내용 |
---|---|
웹 요청 | requests.get(url) |
HTML 파싱 | BeautifulSoup(html, 'html.parser') |
태그 찾기 | find() , find_all() |
텍스트 추출 | get_text(strip=True) |
데이터 저장 | to_csv() |
'Python' 카테고리의 다른 글
여러 페이지 크롤링 자동화 - BeautifulSoup vs Selenium 완전 비교 (0) | 2025.03.31 |
---|---|
Python Selenium으로 동적 웹페이지 크롤링 완전 정복 (기초편) (0) | 2025.03.30 |
외부 CSV 파일 불러오기부터 분석, 저장까지 실전 예제 완전 정복 (0) | 2025.03.28 |
실제 데이터 분석 프로젝트 시작하기 - 인구수 & 평균소득 분석 (기초 예제) (0) | 2025.03.27 |
Pandas + Matplotlib & Seaborn으로 데이터 시각화 완전 입문! (0) | 2025.03.26 |