globalsy_mvp/news_parser.py
belikovme 391757d581 Рефакторинг конфигурации и структуры проекта
- Обновлен config.py с оптимизированными словарями секторов и индексов
- Удалены устаревшие классы exchange.py и moex_class.py
- Модернизирован moex_history.py с улучшенной логикой получения данных
- Обновлен requirements.txt с современными зависимостями для финансовой платформы
- Упрощен open_router.ipynb с фокусом на экономических темах
2025-03-12 17:01:25 +07:00

91 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import datetime
import requests
from bs4 import BeautifulSoup
import pandas as pd
class NewsParser:
def __init__(self):
# Можно использовать один session для всех запросов
self.requests_session = requests.Session()
def parse_news(self, last_days=1):
"""
Парсит новости с Lenta.ru за указанное число последних дней.
:param last_days: количество последних дней, за которые нужно собрать новости.
:return: pd.DataFrame с колонками [dates, topics, titles, content].
"""
dates = []
topics = []
titles = []
contents = []
# Перебираем дни от 0 до last_days-1
for day in range(last_days):
num_pages = 1
# Формируем дату в нужном формате: 'YYYY/MM/DD'
date_str = (datetime.datetime.today() - datetime.timedelta(days=day)).strftime('%Y/%m/%d')
while True:
url = f'https://lenta.ru/{date_str}/page/{num_pages}/'
response = self.requests_session.get(url)
if response.status_code != 200:
break
soup = BeautifulSoup(response.text, 'lxml')
news_list = soup.find_all('a', {"class": "card-full-news _archive"}, href=True)
# Если на странице нет новостей, выходим из цикла пагинации
if len(news_list) == 0:
break
for news in news_list:
dates.append(date_str)
# Заголовок
title_el = news.find('h3', {"class": "card-full-news__title"})
if title_el:
titles.append(title_el.get_text(strip=True))
else:
titles.append('None')
# Рубрика/тема
topic_el = news.find('span', {"class": "card-full-news__info-item card-full-news__rubric"})
if topic_el:
topics.append(topic_el.get_text(strip=True))
else:
topics.append('None')
# Текст статьи
news_url = 'https://lenta.ru' + news['href']
article_req = self.requests_session.get(news_url)
article_soup = BeautifulSoup(article_req.text, 'lxml')
paragraphs = article_soup.find_all('p', class_='topic-body__content-text')
# Склеиваем все абзацы в одну строку
news_content = ' '.join([p.get_text(strip=True) for p in paragraphs])
contents.append(news_content)
num_pages += 1
# Формируем DataFrame
df = pd.DataFrame({
'dates': dates,
'topics': topics,
'titles': titles,
'content': contents
})
# Преобразуем колонки с датами к формату datetime
df['dates'] = pd.to_datetime(df['dates'], errors='coerce')
return df
if __name__ == "__main__":
# Пример использования
parser = NewsParser()
news_df = parser.parse_news() # Сбор новостей за последние 2 дня
print(news_df.head())