[Python 100일 챌린지] Day 60 - 미니 프로젝트: 뉴스 스크래퍼
[Python 100일 챌린지] Day 60 - 미니 프로젝트: 뉴스 스크래퍼
Phase 6 완성! 🎉
scraper.scrape_all()→analyzer.analyze()→storage.save()→ 뉴스 자동 수집 시스템 완성!** 😊9일간 배운 모든 웹 기술로 실전 뉴스 스크래퍼 제작! requests + BeautifulSoup + 크롤링 + 데이터 분석까지!
(50-60분 완독 ⭐⭐⭐⭐)
🎯 오늘의 학습 목표
📚 사전 지식
- Day 51: requests 기초 - HTTP 요청
- Day 52: HTTP 메서드 - REST API
- Day 53: BeautifulSoup - HTML 파싱
- Day 54: 웹 스크래핑 고급 - 동적 콘텐츠
- Day 55: API 설계 - API 구조
- Day 56: RESTful API - REST 원칙
- Day 57: API 인증 - 인증 방식
- Day 58: 웹 크롤러 - 크롤링 전략
- Day 59: Selenium - 동적 웹페이지
🎯 오늘의 학습 목표 1: Phase 6 내용 복습하기
Phase 6에서 배운 내용
Day 51-54: 웹 스크래핑 기초
- requests 라이브러리
- HTTP 메서드 (GET, POST, PUT, DELETE)
- BeautifulSoup HTML 파싱
- 동적 콘텐츠 스크래핑
Day 55-57: API 설계와 인증
- API 설계 원칙
- RESTful API 구현
- API 인증 방식 (API Key, OAuth, JWT)
- API 문서화
Day 58-59: 고급 크롤링
- 웹 크롤러 구현
- URL 관리와 방문 기록
- Selenium 브라우저 자동화
- 대기 전략과 예외 처리
오늘 만들 프로젝트
뉴스 스크래퍼 - Phase 6의 모든 웹 스크래핑 기술을 활용합니다!
🎯 오늘의 학습 목표 2: 뉴스 스크래퍼 시스템 설계하기
프로젝트 목표
뉴스 수집 및 분석 시스템:
- 여러 뉴스 사이트 스크래핑
- 데이터 정제 및 저장
- 키워드 분석
- JSON/CSV 출력
- 일정 자동화
📁 프로젝트 구조
1
2
3
4
5
6
news_scraper/
├── scraper.py # 스크래퍼
├── parser.py # 파서
├── storage.py # 저장
├── analyzer.py # 분석
└── main.py # 메인
🎯 오늘의 학습 목표 3: 웹 스크래핑과 API를 활용하여 구현하기
1. 뉴스 스크래퍼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# scraper.py
import requests
from bs4 import BeautifulSoup
from datetime import datetime
class NewsScraper:
def __init__(self, sources):
self.sources = sources
def scrape_all(self):
all_articles = []
for source in self.sources:
articles = self.scrape_source(source)
all_articles.extend(articles)
return all_articles
def scrape_source(self, source):
try:
response = requests.get(source['url'], timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
articles = []
elements = soup.select(source['article_selector'])
for element in elements:
article = self._parse_article(element, source)
if article:
articles.append(article)
return articles
except Exception as e:
print(f"❌ {source['name']} 실패: {e}")
return []
def _parse_article(self, element, source):
try:
title = element.select_one(source['title_selector'])
link = element.select_one(source['link_selector'])
if title and link:
return {
'source': source['name'],
'title': title.get_text(strip=True),
'url': link.get('href'),
'scraped_at': datetime.now().isoformat()
}
except:
return None
📊 2. 데이터 분석
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# analyzer.py
from collections import Counter
import re
class NewsAnalyzer:
def __init__(self, articles):
self.articles = articles
def get_statistics(self):
return {
'total': len(self.articles),
'sources': Counter(a['source'] for a in self.articles)
}
def extract_keywords(self, top_n=10):
all_text = ' '.join(a['title'] for a in self.articles)
words = re.findall(r'\b\w+\b', all_text.lower())
return Counter(words).most_common(top_n)
💾 3. 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# storage.py
import json
import csv
class NewsStorage:
def save_json(self, articles, filename='news.json'):
with open(filename, 'w', encoding='utf-8') as f:
json.dump(articles, f, ensure_ascii=False, indent=2)
print(f"✅ JSON 저장: {filename}")
def save_csv(self, articles, filename='news.csv'):
if not articles:
return
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=articles[0].keys())
writer.writeheader()
writer.writerows(articles)
print(f"✅ CSV 저장: {filename}")
🎮 4. 메인 프로그램
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# main.py
from scraper import NewsScraper
from analyzer import NewsAnalyzer
from storage import NewsStorage
NEWS_SOURCES = [
{
'name': 'Example News',
'url': 'https://news.example.com',
'article_selector': '.article',
'title_selector': '.title',
'link_selector': 'a'
}
]
def main():
print("📰 뉴스 스크래핑 시작...")
scraper = NewsScraper(NEWS_SOURCES)
articles = scraper.scrape_all()
print(f"✅ {len(articles)}개 수집")
if articles:
analyzer = NewsAnalyzer(articles)
stats = analyzer.get_statistics()
keywords = analyzer.extract_keywords()
print(f"\n📊 통계: {stats['total']}개")
print(f"🔑 키워드: {keywords[:5]}")
storage = NewsStorage()
storage.save_json(articles)
storage.save_csv(articles)
if __name__ == '__main__':
main()
🎯 오늘의 학습 목표 4: 프로젝트 완성하고 Phase 6 마무리
축하합니다! 🎉
Day 51-60 복습
- Day 51: requests 기초
- Day 52: HTTP 메서드
- Day 53: BeautifulSoup
- Day 54: 스크래핑 고급
- Day 55: API 설계
- Day 56: RESTful API
- Day 57: API 인증
- Day 58: 웹 크롤러
- Day 59: Selenium
- Day 60: 뉴스 스크래퍼 프로젝트
이제와서 시작하는 Python 마스터하기 - Phase 6 완료! 🎉🎉🎉
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.