혼공학습단/혼공파
[혼공파] Beautiful Soup & Flask 로 기상청 날씨 정보 훔치기
sunghoyaaa
2025. 2. 23. 23:00
이 게시글은 혼공학습단(혼공파) 13기의 6주차 과제를 포함하고 있습니다.
Flask와 BeautifulSoup 간단 소개
Flask는 가벼운 웹 프레임워크로 간단한 웹 애플리케이션을 빠르게 개발할 수 있는 도구입니다.
BeautifulSoup은 HTML/XML을 파싱하여 웹 크롤링을 쉽게 할 수 있도록 도와주는 라이브러리입니다.
from flask import Flask
from urllib import request
from bs4 import BeautifulSoup
class WeatherScraper:
"""기상청 날씨 데이터를 가져와 처리하는 클래스"""
def __init__(self, url: str):
"""생성자: 가져올 URL을 설정"""
self.url = url
self.soup = None
def fetch_weather_data(self):
"""웹에서 데이터를 가져와 BeautifulSoup으로 분석"""
response = request.urlopen(self.url)
self.soup = BeautifulSoup(response, "html.parser")
# 파일로 저장하는 이유는 디버그 용도
# print()함수로 사용해서 확인하니까 너무 길어서 짤림...
def save_to_file(self, filename: str = "result.html"):
"""파싱된 데이터를 파일로 저장"""
if self.soup:
with open(filename, "w", encoding="utf-8") as file:
file.write(str(self.soup))
def parse_weather(self) -> str:
"""HTML 문서 전체를 생성하여 반환"""
if not self.soup:
return "<p>날씨 데이터를 불러오지 못했습니다.</p>"
output = """
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[혼공파] - 6주차 과제</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: darkblue; }
h3 { color: darkred; }
hr { border: 0; height: 1px; background: gray; margin: 10px 0; }
</style>
</head>
<body>
<h1>[혼공파] 6주차 마지막 과제</h1>
"""
# header 태그 가져오기 (존재하면 출력)
header_tag = self.soup.select("header")
# html이니까 br 태그로 줄 바꿈 해주기
# select는 return 타입이 array임
header_text = "<br />".join([tag.get_text(strip=True) for tag in header_tag]) if header_tag else "헤더 정보 없음"
output += f"<strong>{header_text}</strong><hr/>"
# 지역별 날씨 정보 추가
# location 별로 나눠져 있음
for location in self.soup.select("location"):
city = location.select_one("city").string
weather = location.select_one("wf").string
min_temp = location.select_one("tmn").string
max_temp = location.select_one("tmx").string
output += f"<h3>{city}</h3>"
output += f"<p>날씨: {weather}</p>"
output += f"<p>최저/최고 기온: {min_temp}/{max_temp}</p>"
output += "<hr />"
# HTML 마무으리
output += """
</body>
</html>
"""
return output
# Flask 웹 서버 생성
app = Flask(__name__)
# 루트 경로로 실행
@app.route("/")
def hello():
"""Flask 라우트에서 WeatherScraper(클래스)를 활용하여 HTML 반환"""
scraper = WeatherScraper("http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108")
scraper.fetch_weather_data()
scraper.save_to_file() # result.html 파일 저장
return scraper.parse_weather() # HTML 문서 전체 반환
기본 숙제 코드 beautiful_flask.py 와 다른 점
- WeatherScraper 클래스를 사용하여 데이터를 가져오고 파싱하는 기능을 모듈화했습니다.
- 지역, 날씨, 최저/최고 기온 데이터 외에 HTML <head> 태그와 RSS에 있는 <header> 데이터를 포함했습니다.
- print()를 사용해서 데이터를 확인하려 했지만, 응답 컨텐츠가 너무 길어 파일로 저장하여 디버깅했습니다.
export FLASK_APP=<파일명>.py # ./beautiful_soup
flask run
http://127.0.0.1:5000
결과
728x90