import requests from bs4 import BeautifulSoup import pandas as pd import streamlit as st import random import time # time 모듈을 임포트 # 네이버 모바일 뉴스 랭킹 URL url = "https://m.news.naver.com/rankingList" # 헤더 설정 (User-Agent 및 Referer 추가) headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36", "Referer": "https://m.news.naver.com/" } # 랜덤 딜레이 함수 def random_delay(min_delay=1, max_delay=3): delay = random.uniform(min_delay, max_delay) time.sleep(delay) # time 모듈의 sleep 함수 사용 # 웹 페이지 요청 및 파싱 response = requests.get(url, headers=headers) soup = BeautifulSoup(response.content, 'html.parser') # 뉴스 리스트 추출 news_list = [] # 새로운 HTML 구조에 맞게 데이터 추출 for news_box in soup.select('div.rankingnews_box'): # 언론사 이름 추출 press_name = news_box.find('strong', class_='rankingnews_name').text.strip() # 각 뉴스 항목을 리스트로 추출 for news_item in news_box.select('ul.rankingnews_list li'): random_delay() # 딜레이 추가 # 순위 번호 추출 rank_tag = news_item.find('em', class_='list_ranking_num') rank = rank_tag.text if rank_tag else 'No Rank' # 제목 추출 title_tag = news_item.find('strong', class_='list_title') title = title_tag.text.strip() if title_tag else 'No Title' # 링크 추출 link = news_item.find('a')['href'] if news_item.find('a') else '#' # 시간 추출 time_tag = news_item.find('span', class_='list_time') time_info = time_tag.text.strip() if time_tag else 'No Time' # 이미지 URL 추출 img_tag = news_item.find('img') image_url = img_tag['src'] if img_tag and 'src' in img_tag.attrs else 'No Image Available' # 데이터 리스트에 추가 news_list.append({ 'Press': press_name, 'Rank': rank, 'Title': title, 'Link': link, 'Time': time_info, 'Image URL': image_url }) # 데이터프레임으로 변환 df = pd.DataFrame(news_list) # Streamlit에서 결과 표시 st.title("Naver Mobile Ranking News Scraper") # 바둑판 모양으로 뉴스를 3개씩 배치 (3열 그리드) columns_per_row = 3 # 뉴스 항목을 바둑판 형태로 출력 for i in range(0, len(df), columns_per_row): cols = st.columns(columns_per_row) # 3열로 그리드 생성 # 각 열에 뉴스 배치 for idx, col in enumerate(cols): if i + idx < len(df): row = df.iloc[i + idx] with col: # 이미지가 있을 경우 출력 if row['Image URL'] != 'No Image Available': st.image(row['Image URL'], use_column_width=True) # 뉴스 제목 하이퍼링크 st.markdown(f"**[{row['Title']}]({row['Link']})**") # 뉴스 언론사와 시간 정보 st.write(f"Press: {row['Press']} | Time: {row['Time']}")