@Nikita637

Как заставить бота ждать ответа пользователя?

Здравствуйте, я пытаюсь написать бота, который выводит расписание межгородский автобусов, с фиксированной точкой отправления у меня все работает, но вот если делать точки отправления разными, то у меня не получается. Я попробовал сделать через registr , но тоже не получилось(хотя возможно я не правильно понял как им пользоваться). Если не трудно, то помогите пожалуйста.
import telebot, wikipedia,re
import requests
from bs4 import BeautifulSoup as BS
import random
import numpy as np

wikipedia.set_lang('ru')



# BOT TOKEN FROM @BOTFATHER
bot = telebot.TeleBot('token')

def bus(URL):

    r=requests.get(URL)
    soup=BS(r.text,'html.parser')
    timebus=soup.find_all('span',class_='o-text-inline o-text-header o-text-headerSmall')
    return[c.text for c in timebus]
URL_a='https://bus.tutu.ru/raspisanie/gorod_Vladimir/gorod_Aleksandrov/'
alecksandrov=bus(URL_a)
URL_g='https://bus.tutu.ru/raspisanie/gorod_Vladimir/gorod_Gus-Hrustalnyj/'
gus_hryst=bus(URL_g)
URL_m='https://bus.tutu.ru/raspisanie/gorod_Vladimir/gorod_Murom/'
myrom=bus(URL_m)
URL_i='https://bus.tutu.ru/raspisanie/gorod_Vladimir/gorod_Ivanovo/'
ivanovo=bus(URL_i)
URL_s='https://bus.tutu.ru/raspisanie/gorod_Vladimir/gorod_Sobinka/'
sobinka=bus(URL_s)




def anektod(url):
    r=requests.get(url)
    soup=BS(r.text,'html.parser')
    anektods=soup.find_all('div',class_='text')
    return [c.text for c in anektods]
URL='https://www.anekdot.ru/author-best/years/?years=anekdot'
rand=anektod(URL)
random.shuffle(rand)
def inputs(message):
    stanstion=message.text



from telebot import types
@bot.message_handler(commands=['start'])
def welcome(message):

    # keyboard
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    item1 = types.KeyboardButton("Информация о боте")
    item2 = types.KeyboardButton("Расписание автобусов")
    wik = types.KeyboardButton('Wiki')
    anektods=types.KeyboardButton('Анекдот')
    markup.add(item1, item2,wik,anektods)

    bot.send_message(message.chat.id,
                     "Добро пожаловать, {0.first_name}! Я бот ,который скажет расписание автобуса или даст инормацию из Wikipedia \nСписок команд:\n/start - начальная страница\n".format(
                         message.from_user, bot.get_me()),
                     parse_mode='html',reply_markup=markup)


@bot.message_handler(content_types=['text'])
def info(message):

    if message.text == 'Информация о боте':
        bot.send_message(message.chat.id,"Приветсвую, Я бот ,который будет предоставлять информацию о расписание автобусов \n P.S. Так же могу рассказать анектод или вывести информацию из wikipedia")

    elif message.text == 'Анекдот':
        bot.send_message(message.chat.id,"Анектод:\n")
        bot.send_message(message.chat.id,rand[0])
        del rand[0]
    elif message.text == 'Wiki':
        bot.send_message(message.chat.id, 'Напиши слово и я найду его в Wikipedia')


    elif message.text =='Расписание автобусов':


        lol = types.ReplyKeyboardMarkup(resize_keyboard=True)
        alex = types.KeyboardButton("Александров")
        myr = types.KeyboardButton("Муром")
        gus = types.KeyboardButton ( "Гусь-Хрустальный" )
        ivan = types.KeyboardButton ( "Иванова" )
        sob = types.KeyboardButton("Собинка")
        vlad = types.KeyboardButton("Владимир")

        lol.add(alex,myr,gus,ivan,sob,vlad)
        bot.send_message(message.chat.id,'Выберите город отправления',reply_markup=lol)

    elif message.text=='Владимир':
        stops = types.ReplyKeyboardMarkup(resize_keyboard=True)
        alex_1 = types.KeyboardButton("Александров")
        myr_1 = types.KeyboardButton("Муром")
        gus_1 = types.KeyboardButton("Гусь-Хрустальный")
        ivan_1 = types.KeyboardButton("Иванова")
        sob_1 = types.KeyboardButton("Собинка")
      

        stops.add(alex_1,myr_1,gus_1,ivan_1,sob_1)
        otvet=bot.send_message(message.chat.id, 'Выберите город прибытия', reply_markup=stops)
        bot.register_message_handler(otvet,inputs)

        if message.text == 'Собинка':
            bot.send_message ( message.chat.id,'Расписание автобусов по маршруту Владимир -> Собинка'  )
            for i in range(len(sobinka)//2+1):

                if i<(len(sobinka)-2):
                    s = sobinka[:-1]

                    bot.send_message(message.chat.id, 'Отправление -> Прибытие ',)
                    bot.send_message ( message.chat.id,  s[i] )
                    bot.send_message ( message.chat.id, s[i+1] )
                    del sobinka[1]
                else:
                    bot.send_message ( message.chat.id, 'Больше рейсов нет' )


        elif message.text == 'Александров':
            bot.send_message ( message.chat.id, 'Расписание автобусов по маршруту Владимир -> Александров:' )
            for i in range(len(alecksandrov)//2+1):

                if i<(len(alecksandrov)-2):
                    s = alecksandrov[:-1]

                    bot.send_message(message.chat.id, 'Отправление -> Прибытие ',)
                    bot.send_message ( message.chat.id,  s[i] )
                    bot.send_message ( message.chat.id, s[i+1] )
                    del alecksandrov[1]
                else:
                    bot.send_message ( message.chat.id, 'Больше рейсов нет' )



        elif message.text == 'Муром':
            bot.send_message ( message.chat.id, 'Расписание автобусов по маршруту Владимир -> Муром:' )
            for i in range ( len ( myrom ) //2+1 ):

                if i < (len ( myrom ) - 2):
                    s = myrom[:-1]

                    bot.send_message(message.chat.id, 'Отправление -> Прибытие ', )
                    bot.send_message(message.chat.id, s[i])
                    bot.send_message(message.chat.id, s[i + 1])
                    del myrom[1]
                else:
                    bot.send_message ( message.chat.id, 'Больше рейсов нет' )


        elif message.text == 'Гусь-Хрустальный':
            bot.send_message ( message.chat.id, 'Расписание автобусов по маршруту Владимир -> Гусь-Хрустальный:' )
            for i in range ( len ( gus_hryst ) //2+1 ):

                if i < (len ( gus_hryst ) - 2):
                    s = gus_hryst[:-1]

                    bot.send_message(message.chat.id, 'Отправление -> Прибытие ', )
                    bot.send_message(message.chat.id, s[i])
                    bot.send_message(message.chat.id, s[i + 1])
                    del gus_hryst[1]
                else:
                    bot.send_message ( message.chat.id, 'Больше рейсов нет' )


        elif message.text == 'Иванова':
            bot.send_message ( message.chat.id, 'Расписание автобусов по маршруту Владимир -> Иванова:' )
            for i in range ( len ( ivanovo ) //2+1 ):

                if i < (len ( ivanovo ) - 2):
                    s = ivanovo[:-1]

                    bot.send_message(message.chat.id, 'Отправление -> Прибытие ', )
                    bot.send_message(message.chat.id, s[i])
                    bot.send_message(message.chat.id, s[i + 1])
                    del ivanovo[1]
                else:
                    bot.send_message ( message.chat.id, 'Больше рейсов нет' )
        else:
            bot.send_message(message.chat.id,'в разработке')

    else:
        bot.send_message ( message.chat.id,'По вашему запросу было найдено вот это:')
        bot.send_message(message.chat.id, getwiki(message.text))
# RUN
bot.polling(none_stop=True)
  • Вопрос задан
  • 79 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Ну для начала твоя лесенка из if-elif-elif-... - плохое решение.
Сделай нормальную структуру данных вместо пачки переменных. Используй словарь, или ещё что. Например, такого вида:
# словарь, где ключ - строка с названием пунка отправления, а значение - ещё словарь,
#   где ключ - строка с названием пункта назначения, а значение - список,
#     где элементы - пары строк ("время отправления", "время прибытия")
# Тогда с таким словарём можно будет работать так:
bus_timetable: dict[str, dict[str, list[tuple[str, str]]]] = {
    # ты словарь заполняешь по результатам парсинга, ну и то хорошо
    # я для примера запишу прямо так
    'Владимир' : {
        'Муром': [
            ('8:00', '11:00'),
            ('9:00', '12:00'),
            ('10:00', '13:00'),
        ],
    },
}
point_from = 'Владимир'
point_to = 'Муром'
# для примера вывожу в консоль, для бота перепишешь сам
print(f'Автобус из {point_from} в {point_to}')  
for departure, arrival in bus_timetable[point_from][point_to]:
    print(f'Отходит в {departure}, прибывает в {arrival}')

Тогда тебе не потребуется делать кучу веток для разных городов, достаточно лишь определить значения point_from и point_to. Более того, ты можешь просто перечислить ключи внешнего словаря при создании кнопок:
kbd_from = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = [types.KeyboardButton(point_from) for point_from in bus_timetable]  # список кнопок
kbd_from.add(*buttons)  # если надо добавить все кнопки сразу

Похожий приём возможен и для определения кнопок для городов назначения.

А теперь по тому, как сделать выбор. Тут есть два варианта, но давай пока поговорим о ReplyKeyboardMarkup, которую ты используешь.
Если ты хочешь использовать ReplyKeyboardMarkup, то стоит помнить - её кнопки дают тот же эффект, как если бы пользователь просто ввёл текст кнопки сам. Поэтому тебе потребуется использовать register_next_step_handler(). Ты не привёл код своей попытки, но в целом идея несложная. В основном обработчике события ты проверяешь, что текст сообщения содержится в bus_timetable (оператор in в помощь) - это значит, что текст сообщения содержит название известного боту города.
Тогда ты делаешь вызов register_next_step_handler() и ставишь обработчик второго сообщения. Единственное "но": тебе нужно будет обработчику передать первый выбранный город. Это будет выглядеть как-то так:
@bot.message_handler(content_types=['text'])
def first_message_handler(message):
    if message.text in bus_timetable:  # назвали известный город? Это пункт отправления
        kbd = ...  # тут определяешь клавиатуру, опираясь на города в bus_timetable[message.text]
        response = bot.reply_to(message, "А теперь назовите пункт назначения", reply_markup=kbd)
        # обрати внимание: все параметры после указания функции second_message_handler будут
        # переданы в эту функцию при её вызове. А вызвана она будет, когда пользователь ответит.
        bot.register_next_step_handler(response, second_message_handler, message.text)
    elif ...  # нам назвали не город - тут можно проверить другие команды

def second_message_handler(message, point_from):
    # а эта функция будет вызвана только когда пользователь уже назвал пункт отправления
    # point_from будет содержать название города, отправленное пользователем.
    if message.text in bus_timetable[point_from]:  # нам назвали допустимый пункт назначения
        bus_rides = bus_timetable[point_from][message.text]  # список рейсов
        ...  # дальше перебираем список bus_rides и выводим его пользователю
    else:  # пользователь назвал что-то другое
        ...  # говорим пользователю, что он дурак
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы