파이썬으로 매일 아침 뉴스 헤드라인 이메일 받기

파이썬으로 뉴스 헤드라인을 자동으로 수집하고 이메일로 보내는 봇을 만들어보세요. 매일 아침 출근길에 오늘의 주요 뉴스를 한눈에 볼 수 있어요. macOS 환경에서 간단하게 구현할 수 있는 방법을 알려드릴게요.


신문을 읽는 비즈니스맨과 마케팅 전략 설명이 담긴 일간 뉴스 레이아웃


필요한 라이브러리 설치하기


터미널을 열고 다음 명령어로 필요한 패키지를 설치해요:


pip install requests beautifulsoup4 schedule newspaper3k feedparser


각 라이브러리의 역할은 다음과 같아요:


  • requests: 웹페이지 데이터 가져오기
  • beautifulsoup4: HTML 파싱
  • schedule: 자동 실행 스케줄링
  • newspaper3k: 뉴스 기사 전문 추출
  • feedparser: RSS 피드 파싱

뉴스 헤드라인 수집하기


네이버 뉴스에서 헤드라인을 가져오는 기본 코드예요:


import requests
from bs4 import BeautifulSoup

def get_naver_headlines():
    url = 'https://news.naver.com/'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    headlines = []
    # 네이버 뉴스 헤드라인 선택자 (2025년 기준)
    for item in soup.select('.hdline_article_tit'):
        title = item.text.strip()
        link = 'https://news.naver.com' + item.a['href']
        headlines.append({'title': title, 'link': link})
    
    return headlines[:10]  # 상위 10개만 반환


RSS 피드를 활용하면 더 안정적으로 뉴스를 수집할 수 있어요:


import feedparser

def get_rss_headlines():
    # 주요 언론사 RSS 피드 URL들
    feeds = [
        'http://rss.donga.com/total.xml',
        'https://rss.hankyung.com/feed/all.xml',
        'http://www.khan.co.kr/rss/rssdata/total_news.xml'
    ]
    
    all_headlines = []
    for feed_url in feeds:
        feed = feedparser.parse(feed_url)
        for entry in feed.entries[:5]:  # 각 언론사당 5개씩
            all_headlines.append({
                'title': entry.title,
                'link': entry.link,
                'published': entry.get('published', '')
            })
    
    return all_headlines


newspaper3k로 기사 본문까지 수집하기


단순 헤드라인이 아닌 기사 요약까지 포함하고 싶다면 newspaper3k를 활용해요:


from newspaper import Article

def get_article_with_summary(url):
    try:
        article = Article(url, language='ko')
        article.download()
        article.parse()
        
        # 본문 첫 200자를 요약으로 사용
        summary = article.text[:200] + '...' if len(article.text) > 200 else article.text
        
        return {
            'title': article.title,
            'summary': summary,
            'url': url
        }
    except Exception as e:
        print(f"기사 파싱 실패: {e}")
        return None


Gmail로 이메일 자동 발송하기


Gmail SMTP를 사용해서 수집한 뉴스를 이메일로 보내요. macOS의 키체인에 앱 비밀번호를 저장하면 더 안전해요:


import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_gmail(subject, body, to_email):
    # Gmail 설정
    gmail_user = 'your_email@gmail.com'
    gmail_password = 'your_app_password'  # 2단계 인증 후 앱 비밀번호 사용
    
    # 이메일 구성
    msg = MIMEMultipart()
    msg['From'] = gmail_user
    msg['To'] = to_email
    msg['Subject'] = subject
    
    # HTML 형식으로 본문 작성
    html_body = f"""
    <html>
      <body>
        <h2>오늘의 주요 뉴스</h2>
        {body}
      </body>
    </html>
    """
    
    msg.attach(MIMEText(html_body, 'html'))
    
    # Gmail SMTP 서버로 전송
    try:
        server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
        server.login(gmail_user, gmail_password)
        server.send_message(msg)
        server.quit()
        print("이메일 전송 성공!")
    except Exception as e:
        print(f"이메일 전송 실패: {e}")


뉴스를 HTML 형식으로 예쁘게 포맷하기


수집한 뉴스를 보기 좋은 HTML 형식으로 변환해요:


def format_news_html(headlines):
    html_content = ""
    
    for idx, news in enumerate(headlines, 1):
        html_content += f"""
        <div style="margin-bottom: 20px; padding: 10px; border-bottom: 1px solid #ddd;">
            <h3 style="color: #333;">{idx}. {news['title']}</h3>
            <a href="{news['link']}" style="color: #0066cc; text-decoration: none;">기사 보기</a>
            {f'<p style="color: #666; margin-top: 10px;">{news.get("summary", "")}</p>' if news.get('summary') else ''}
        </div>
        """
    
    return html_content


모든 기능을 합친 완성 코드


이제 모든 기능을 하나로 합쳐서 자동화 봇을 완성해요:


import schedule
import time
from datetime import datetime

def news_bot_job():
    print(f"뉴스 수집 시작: {datetime.now()}")
    
    # 1. 뉴스 헤드라인 수집
    headlines = get_rss_headlines()
    
    # 2. 기사 요약 추가 (선택사항)
    for news in headlines[:5]:  # 상위 5개만 요약
        article_data = get_article_with_summary(news['link'])
        if article_data:
            news['summary'] = article_data['summary']
    
    # 3. HTML 형식으로 포맷
    html_body = format_news_html(headlines)
    
    # 4. 이메일 발송
    today = datetime.now().strftime("%Y년 %m월 %d일")
    subject = f"[뉴스봇] {today} 오늘의 주요 뉴스"
    
    send_gmail(subject, html_body, 'recipient@example.com')
    
    print("뉴스 발송 완료!")

# 매일 오전 7시에 실행
schedule.every().day.at("07:00").do(news_bot_job)

# 테스트용: 즉시 한 번 실행
# news_bot_job()

# 스케줄러 실행
print("뉴스봇이 시작되었어요. 매일 오전 7시에 뉴스를 보내드릴게요.")
while True:
    schedule.run_pending()
    time.sleep(60)


macOS에서 백그라운드 실행하기


터미널을 닫아도 계속 실행되도록 설정하는 방법이에요:


방법 1: nohup 사용


nohup python3 news_bot.py > news_bot.log 2>&1 &


방법 2: screen 사용


# screen 설치 (Homebrew 필요)
brew install screen

# 새 세션 시작
screen -S newsbot

# 봇 실행
python3 news_bot.py

# 세션 분리: Ctrl+A, D
# 다시 연결: screen -r newsbot


방법 3: launchd 사용 (macOS 추천)


~/Library/LaunchAgents/com.user.newsbot.plist

파일을 만들어요:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.user.newsbot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/python3</string>
        <string>/Users/your_username/newsbot/news_bot.py</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/Users/your_username/newsbot/output.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/your_username/newsbot/error.log</string>
</dict>
</plist>


그리고 다음 명령어로 등록해요:


launchctl load ~/Library/LaunchAgents/com.user.newsbot.plist


추가 기능 아이디어


뉴스봇을 더 똑똑하게 만들 수 있는 방법들이에요:


키워드 필터링


def filter_by_keywords(headlines, keywords):
    filtered = []
    for news in headlines:
        for keyword in keywords:
            if keyword in news['title']:
                filtered.append(news)
                break
    return filtered

# 사용 예시
my_keywords = ['AI', '인공지능', '주식', '경제']
filtered_news = filter_by_keywords(headlines, my_keywords)


중복 제거


def remove_duplicates(headlines):
    seen_titles = set()
    unique_news = []
    
    for news in headlines:
        # 제목의 처음 20자로 중복 체크
        title_key = news['title'][:20]
        if title_key not in seen_titles:
            seen_titles.add(title_key)
            unique_news.append(news)
    
    return unique_news


카테고리별 분류


def categorize_news(headlines):
    categories = {
        '경제': ['주식', '환율', '금리', '부동산'],
        'IT': ['AI', '스타트업', '애플', '구글'],
        '정치': ['국회', '대통령', '선거', '정책']
    }
    
    categorized = {cat: [] for cat in categories}
    categorized['기타'] = []
    
    for news in headlines:
        categorized_flag = False
        for cat, keywords in categories.items():
            for keyword in keywords:
                if keyword in news['title']:
                    categorized[cat].append(news)
                    categorized_flag = True
                    break
            if categorized_flag:
                break
        
        if not categorized_flag:
            categorized['기타'].append(news)
    
    return categorized


실제로 운영해보면 매일 아침 일정한 시간에 뉴스가 도착하는 것이 얼마나 편리한지 알게 될 거예요. 특히 관심 분야의 키워드를 설정해두면 놓치는 뉴스 없이 효율적으로 정보를 얻을 수 있어요.


코드를 조금씩 수정하면서 자신만의 뉴스봇으로 발전시켜보세요. 날씨 정보를 추가하거나, 주식 시황을 포함시키는 것도 좋은 아이디어예요.


네이버 카페 크롤링 자동화, 키워드 수집부터 알림까지 전체 코드 공개