- Обновлен config.py с оптимизированными словарями секторов и индексов - Удалены устаревшие классы exchange.py и moex_class.py - Модернизирован moex_history.py с улучшенной логикой получения данных - Обновлен requirements.txt с современными зависимостями для финансовой платформы - Упрощен open_router.ipynb с фокусом на экономических темах
91 lines
3.7 KiB
Python
91 lines
3.7 KiB
Python
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())
|