Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- """
- Полноценная реализация чат-бота для Telegram.
- Бот обрабатывает входящие сообщения следующим образом:
- 1. Получает сообщение от пользователя.
- 2. С помощью NLTK:
- - Токенизирует текст,
- - Удаляет стоп-слова,
- - Оставляет только слова (без знаков препинания и чисел).
- 3. Приводит слова к нормальной форме (лемматизация) с помощью spaCy.
- 4. Загружает таблицу "Лекарства.xlsx" с данными (предполагается, что в первой колонке находятся названия лекарств).
- 5. Для каждого лемматизированного токена производит поиск по столбцам таблицы и подсчитывает количество совпадений.
- 6. Если совпадения обнаружены только в первом столбце – выводит список лекарств (уникальные значения найденных строк).
- 7. В противном случае – сообщает, что условие не выполнено.
- 8. Бот также обрабатывает стандартные команды /start, /help и команду "Выход" для завершения работы.
- """
- import telebot
- import pandas as pd
- import nltk
- from nltk.tokenize import word_tokenize
- from nltk.corpus import stopwords
- import spacy
- # Загружаем необходимые ресурсы NLTK
- nltk.download('punkt')
- nltk.download('stopwords')
- # Загружаем spaCy модель для русского языка
- # Для корректной работы требуется модель "ru_core_news_md" (ее можно установить командой: python -m spacy download ru_core_news_md)
- nlp = spacy.load("ru_core_news_md")
- # Загружаем Excel-файл с лекарствами.
- # Файл "Лекарства.xlsx" должен находиться в рабочем каталоге.
- try:
- df = pd.read_excel("Лекарства.xlsx")
- except Exception as e:
- print("Ошибка при загрузке файла Excel:", e)
- df = None
- # Инициализация Telegram-бота (укажите свой токен)
- bot = telebot.TeleBot('ВАШ_ТОКЕН_ЗДЕСЬ') # замените 'ВАШ_ТОКЕН_ЗДЕСЬ' на реальный токен
- def process_message(text):
- """
- Обработка входящего текста:
- 1. Приведение к нижнему регистру.
- 2. Токенизация с помощью NLTK.
- 3. Удаление стоп-слов и оставление только буквенных токенов.
- 4. Лемматизация с помощью spaCy.
- Возвращает список нормализованных токенов (лемм).
- """
- # Приводим текст к нижнему регистру
- text = text.lower()
- # Токенизируем текст
- tokens = word_tokenize(text, language="russian")
- # Фильтруем токены: оставляем только слова и удаляем стоп-слова
- filtered_tokens = [token for token in tokens if token.isalpha() and token not in stopwords.words("russian")]
- # Лемматизация с помощью spaCy: объединяем токены в строку и анализируем
- doc = nlp(" ".join(filtered_tokens))
- lemmas = [token.lemma_ for token in doc]
- return lemmas
- def search_tokens_in_table(tokens, dataframe):
- """
- Ищет в таблице совпадения по каждому столбцу для списка токенов.
- Параметры:
- tokens: список нормализованных токенов (строк)
- dataframe: объект pandas.DataFrame, загруженный из Excel
- Возвращает:
- col_matches: словарь, где ключ – имя столбца, значение – количество совпадений
- col_matches_rows: словарь, где ключ – имя столбца, значение – список индексов строк,
- в которых обнаружены совпадения.
- """
- col_matches = {col: 0 for col in dataframe.columns}
- col_matches_rows = {col: [] for col in dataframe.columns}
- # Для каждого токена ищем его наличие в каждой ячейке таблицы
- for token in tokens:
- for col in dataframe.columns:
- for idx, value in dataframe[col].iteritems():
- if pd.notnull(value):
- # Приводим значение ячейки к строке, приводим к нижнему регистру и проверяем наличие токена
- if token in str(value).lower():
- col_matches[col] += 1
- col_matches_rows[col].append(idx)
- return col_matches, col_matches_rows
- # Определяем функцию для ветвления логики в зависимости от результатов поиска
- def analyze_results(col_matches, col_matches_rows, dataframe):
- """
- Анализирует результаты поиска.
- Если совпадения есть только в первом столбце, возвращает список лекарств по найденным индексам.
- Иначе возвращает сообщение о том, что условие не выполнено.
- """
- # Предполагаем, что первый столбец содержит названия лекарств
- primary_col = dataframe.columns[0]
- other_cols = [col for col in dataframe.columns if col != primary_col]
- # Если в первом столбце есть совпадения и в остальных нет
- if col_matches[primary_col] > 0 and all(col_matches[col] == 0 for col in other_cols):
- # Получаем уникальные значения (названия лекарств) для найденных строк
- matched_indices = set(col_matches_rows[primary_col])
- drugs = dataframe.loc[matched_indices, primary_col].unique()
- return "Найденные лекарства: " + ", ".join([str(drug) for drug in drugs])
- else:
- return "Результаты поиска не удовлетворяют условию (совпадения обнаружены не только в первом столбце)."
- # Обработчик команд /start и /help
- @bot.message_handler(commands=['start', 'help'])
- def send_welcome(message):
- bot.reply_to(message, 'Привет! Чем могу помочь? Напиши "Выход" для завершения работы.')
- # Обработчик текстовых сообщений
- @bot.message_handler(content_types=['text'])
- def get_text_messages(message):
- # Если пользователь пишет "Выход", завершаем работу бота
- if message.text.strip().lower() == "выход":
- bot.send_message(message.from_user.id, "Бот завершает работу. До свидания!")
- exit_program()
- return
- # Обрабатываем входящий текст: нормализация и лемматизация
- tokens = process_message(message.text)
- print("Обработанные токены:", tokens)
- # Если таблица не загружена, выводим сообщение об ошибке
- if df is None:
- bot.send_message(message.from_user.id, "Ошибка: не удалось загрузить таблицу с данными.")
- return
- # Производим поиск токенов в таблице
- col_matches, col_matches_rows = search_tokens_in_table(tokens, df)
- print("Совпадения по столбцам:", col_matches)
- # Анализируем результаты поиска
- result = analyze_results(col_matches, col_matches_rows, df)
- # Отправляем ответ пользователю
- bot.send_message(message.from_user.id, result)
- def exit_program():
- """
- Функция для завершения работы бота.
- """
- print("Завершение работы программы...")
- bot.stop_polling()
- quit()
- # Запуск бота в режиме polling (постоянное прослушивание сообщений)
- if __name__ == "__main__":
- print("Запуск бота...")
- bot.polling(none_stop=True, interval=0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement