Как с помощью команд telegram бота выводить отдельные данные погоды
import telebot
from pyowm.owm import OWM
from pyowm.utils.config import get_default_config
bot = telebot.TeleBot('1:AA')
@bot.message_handler(commands=['start'])
def hello(message):
bot.send_message(message.chat.id, 'Добро пожаловать, я бот знающий погоду во всем мире' + '\n' +
'Чтобы узнать погоду напишите в чат название любого города\n/help - все команды бота')
@bot.message_handler(commands=['help'])
def help(message):
bot.send_message(message.chat.id, '/start - запуск бота\n/help - команды бота\nНапишите в чат название города для получения информации о погоде')
@bot.message_handler(content_types=['text'])
def test(message):
try:
place = message.text
config_dict = get_default_config()
config_dict['language'] = 'ru'
owm = OWM('0...', config_dict)
mgr = owm.weather_manager()
observation = mgr.weather_at_place(place)
w = observation.weather
t = w.temperature('celsius')
t1 = t['temp']
t2 = t['feels_like']
t3 = t['temp_max']
t4 = t['temp_min']
wi = w.wind()['speed']
humi = w.humidity
cl = w.clouds
dt = w.detailed_status
ti = w.reference_time('iso')
pr = w.pressure['press']
vd = w.visibility_distance
st = w.status
bot.send_message(message.chat.id, 'В городе ' + str(place) + ' температура ' + str(t1) + ' C' + '\n' +
'Максимальная температура ' + str(t3) + 'C' + '\n'+
'Минимальная температура ' + str(t4) + 'C' + '\n' +
'Ощущается как ' + str(t2) + 'C' + '\n' +
'Скорость ветра ' + str(wi) + 'м/с' + '\n' +
'Давление ' + str(pr) + 'мм.рт.ст' + '\n' +
'Влажность ' + str(humi) + '%' + '\n' +
'Видимость ' + str(vd) + 'метров' + '\n'
'Статус ' + str(st) + '\n' + str(dt) )
except:
bot.send_message(message.chat.id, ' Такой город не найден')
print(str(message.text), '- не найден')
bot.polling(none_stop=True, interval=0)
Ответы (1 шт):
несмотря на правильные вопросы MyZik и passant, я всё же хочу ответить на данный вопрос:
использование @bot.message_handler(content_types=['text']) будет запускать поиск погоды для всех сообщений, будь-то город или название фрукта
для удобства я вынес получение погоды в отдельную функцию с возвратом в виде словаря:
def owm_info(place):
config_dict = get_default_config()
config_dict['language'] = 'ru'
owm = OWM(owm_token, config_dict)
mgr = owm.weather_manager()
w = mgr.weather_at_place(place).weather
t = w.temperature('celsius')
temp = t['temp']
feels_like = t['feels_like']
temp_max = t['temp_max']
temp_min = t['temp_min']
wind_speed = w.wind()['speed']
humidity = w.humidity
clouds = w.clouds
detailed_status = w.detailed_status
reference_time = w.reference_time('iso')
pressure = w.pressure['press']
visibility_distance = w.visibility_distance
status = w.status
return {'temp': f'Температура: {temp} C', 'feels_like': f'Ощущается как: {feels_like} C',
'temp_max': f'Температура / max: {temp_max} C', 'temp_min': f'Температура / min: {temp_min} C'}
дальше хэндлер на команду и метод ожидания ввода:
@bot.message_handler(commands=['tmp'])
def get_tmp(message):
msg = bot.send_message(message.chat.id, 'напишите название любого города')
bot.register_next_step_handler(msg, get_tmp_2)
это позволит дождаться ввода от пользователя и перейти к следующему шагу:
def get_tmp_2(message):
w = owm_info(message.text)
bot.send_message(message.chat.id, f'{w["temp"]}\n{w["feels_like"]}\n{w["temp_max"]}\n{w["temp_min"]}')
возврат данных о погоде в виде словаря очень удобен - можно выводить конкретные значения по понятным ключам и основной код бота не нагружать форматированием конечного сообщения для пользователя
можно сделать без ожидание ввода - "аргумент" к команде:
@bot.message_handler(commands=['temp'])
def get_temp(message):
w = owm_info(message.text.split(maxsplit=1)[1])
bot.send_message(message.chat.id, f'{w["temp"]}\n{w["feels_like"]}\n{w["temp_max"]}\n{w["temp_min"]}')
для этого потребуется отправить боту "/temp город"
а можно пойти ещё дальше и сделать с помощью inline кнопок:
создадим словарь с данными для кнопок - text и callack_data:
button = {'temp': 'Температура', 'feels_like': 'Ощущается как', 'temp_max': 'Температура / max', 'temp_min': 'Температура / min'}
функцию создания клавиатуры из словаря:
def kb_btn(place):
kb = InlineKeyboardMarkup()
btn = []
for i in button.items():
bt = InlineKeyboardButton(text=i[1], callback_data="['w', '" + i[0] + "', '" + place + "']")
btn.append(bt)
kb.add(*btn)
return kb
и коллбэк хэндлер:
@bot.callback_query_handler(func=lambda call: True)
def inline_kb(call):
if call.data.startswith("['w"):
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
text=f'{owm_info(ast.literal_eval(call.data)[2])[ast.literal_eval(call.data)[1]]}',
reply_markup=kb_btn(ast.literal_eval(call.data)[2]))
обратите внимание на startswith - возвращает флаг, указывающий на то, начинается ли строка с указанного префикса (callback_data="['w'...) т.к. callback_data составная - префикс, ключ словаря и город, а так же ast.literal_eval который позволит получить все части callback_data по индексам.
пожалуйста! не копируйте код в тупую, разберитесь в предоставленном вам ответе, цените время потраченное на ответ.