Автор оригинала: Ekapope Viriyakovithya.
Полное подеение руководства по созданию собственного боевого бота погоды.
Утренняя рутина всегда стресса. Разве это не было бы замечательно, если у вас было меньше всего беспокоиться утром?
Что, если у вас была настраиваемая погода Bott Bot, который отправил вам короткое сообщение, только когда появился дождь над вашим заранее определенным порогом?
Не тратьте время, проверяя погоду в отдельном приложении. Может быть жить на вашем Messenger Chatbox!
Что вам нужно?
- Python 3.6 (или раньше) с пандами и fbchat Установлены пакеты
pip install fbchat
- Accuweather Developer учетной записи Свободный пакет должен быть достаточно. Он обеспечивает 50 звонков в день с 1 ключевой учетной записью/разработчиком.
Давайте начнем!
В конце этого, у вас будет 3 файла в папке сценариев:
Клавиши .py : Чтобы сохранить ваш почтовый адрес Facebook, пароль и ключ Accuweather API
paramspy : Для хранения порогового и прогноза прогноза погоды
main.py : Это главный скрипт, он позвонит на Keys.py и params.py
1. Настройте учетную запись Facebook и Accuweather API
Во-первых, давайте поставьте свою учетную запись в Клавиши .py файл.
# Your Facebook usersname (email) FB_USERNAME= "" # Your Facebook password FB_PASSWORD= "" # Your AccuWeather API key ACCUWEATHER_API_KEY= ""
2. Настройка параметров
На этом этапе мы определим порог для вероятности вероятности дождя или снега, задержать время между каждым запросом и сообщением, а также местоположением.
В настоящее время мы устанавливаем порог на 25% как для дождя, так и на снегу. Мы получим сообщение о предупреждении только в том случае, если данные Accuweather показывают вероятность ≥ 25%.
Приведенные ниже скрипты запрошу данные от Accuweather каждые 1 час () и отправят сообщение каждые 4 часа ().
Эти параметры будут храниться в paramspy файл.
# Define % threshold for probability of rain and snow. # The msg will be sent out if the % chance exceed the value RAIN_THRESHOLD = 25 SNOW_THRESHOLD = 25 # time between Accuweather request (in hour) UPDATE_INTERVAL_HR = 1 # delay time between msg (in hour) DELAY_TIME_HR = 4 # location id # for example, https://www.accuweather.com/en/fr/lille/135564/weather-forecast/135564 # location id is 135564 LOCATION_ID = "135564"
3. Получить данные от Accuweather
Теперь здесь приходит веселая часть. Теперь мы будем работать над главным сценарием.
Если вы планируете запустить его на месте, настройте свой каталог и импортируйте клавиши и параметры. Убедитесь, что вы поставили Клавиши .py и paramspy в той же папке, что и это main.py скрипт
#set the current directory import os os.chdir(r".\YOUR_PATH") ############################################################################### #import keys and parameters other scripts in the same folder from keys import FB_USERNAME,FB_PASSWORD,ACCUWEATHER_API_KEY from params import RAIN_THRESHOLD,SNOW_THRESHOLD,UPDATE_INTERVAL_HR,DELAY_TIME_HR,LOCATION_ID
Импорт требуемых модулей.
#import required modules import urllib import urllib.parse import json import time import requests import pandas as pd import logging import sys from fbchat import Client from fbchat.models import * from datetime import datetime
Определите «URL_Page», который будет запрошен в этом примере, мы возьмем 12-часовой почасовой прогноз. Преобразуйте наше время обновления/задержки в секунды.
url_page = "http://dataservice.accuweather.com/forecasts/v1/hourly/12hour/"+str(LOCATION_ID)+"?apikey="+ACCUWEATHER_API_KEY+"&details=true&metric=true" #convert hours to seconds update_interval_sec = 60*60*UPDATE_INTERVAL_HR delay_time_sec = 60*60*DELAY_TIME_HR
Затем запросите данные и поместите в PandaS DataFrame под названием «JSON_DF».
На данный момент мы можем осмотреть восстановленную таблицу. Извлечь и переименуйте элементы, которые нам нужны. В этом примере нам понадобится Accuweather Link,% дождя,% снега, дата и время в желаемом формате.
json_page = urllib.request.urlopen(url_page) json_data = json.loads(json_page.read().decode()) json_df = pd.DataFrame(json_data) # set maximum width, so the links are fully shown and clickable pd.set_option('display.max_colwidth', -1) json_df['Links'] = json_df['MobileLink'].apply(lambda x: 'Link') json_df['Real Feel (degC)'] = json_df['RealFeelTemperature'].apply(lambda x: x.get('Value')) json_df['Weather'] = json_df['IconPhrase'] json_df['Percent_Rain'] = json_df['RainProbability'] json_df['Percent_Snow'] = json_df['SnowProbability']
Если мы посмотрим внимательно, столбец «DateTime» немного сложно извлечь и нуждается в некоторой работе. После очистки сохраните его в переменной «ustrem_retried_dateTime».
json_df[['Date','Time']] = json_df['DateTime'].str.split('T', expand=True) # trim the time to hh:mm format, change to str json_df[['Time']] = json_df['Time'].str.split('+', expand=True)[0].astype(str).str[:5] current_retrieved_datetime = str(json_df['Date'][0])+' '+str(json_df['Time'][0])
Далее, напишите состояние IF-Ever, чтобы настроить сообщение о предупреждении. Восстановленная таблица предоставляет нам прогноз 12 часов. Мы проверим каждый элемент под дождем, так и снегами и возвращаем сообщение, если вероятность выше порога.
Во-первых, инициализируйте сообщение о предупреждении для каждого случая.
rain_msg="" snow_msg=""
Проверьте столбцы «Процентірейн» и «проценты_snow», флаг с 1, если вероятность% приведена выше пороговое значение (или 0 в противном случае).
Суммируйте столбцы и измените «RAIN_MSG» и «SNOW_MSG».
# check % Rain column, return rain_msg json_df.loc[json_df['Percent_Rain'] >= RAIN_THRESHOLD, 'Rain_Alert'] = 1 json_df.loc[json_df['Percent_Rain'] < RAIN_THRESHOLD, 'Rain_Alert'] = 0 if (sum(json_df['Rain_Alert']) > 0): rain_msg = 'There is ' \ +str(json_df['Percent_Rain'][json_df['Rain_Alert']==1][0]) \ +' % chance of rain' \ +' at ' \ +str(json_df['Time'][json_df['Rain_Alert']==1][0]) # check % Snow column json_df.loc[json_df['Percent_Snow'] >= SNOW_THRESHOLD, 'Snow_Alert'] = 1 json_df.loc[json_df['Percent_Snow'] < SNOW_THRESHOLD, 'Snow_Alert'] = 0 if (sum(json_df['Snow_Alert']) > 0): snow_msg = 'There is ' \ +str(json_df['Percent_Snow'][json_df['Percent_Snow']==1][0]) \ +' % chance of snow' \ +' at ' \ +str(json_df['Time'][json_df['Percent_Snow']==1][0])
Инициализируйте «ALERT_MSG», измените сообщения, если есть какой-либо «RAIN_MSG» или «Snow_Msg».
alert_msg ="" if(len(rain_msg)|len(snow_msg)!=0): alert_msg = rain_msg +" "+snow_msg
Добавьте ссылку на переменную «Link_for_Click», это будет прикреплена к сообщению, когда мы отправим позже.
link_for_click = json_df['MobileLink'][0]
До этого момента мы теперь можем обернуть их в функцию. Не волнуйтесь, если вы потерялись, я поставил их вместе ниже.
def func_get_weather(url_page): json_page = urllib.request.urlopen(url_page) json_data = json.loads(json_page.read().decode()) json_df = pd.DataFrame(json_data) # set maximum width, so the links are fully shown and clickable pd.set_option('display.max_colwidth', -1) json_df['Links'] = json_df['MobileLink'].apply(lambda x: 'Link') json_df['Real Feel (degC)'] = json_df['RealFeelTemperature'].apply(lambda x: x.get('Value')) json_df['Weather'] = json_df['IconPhrase'] json_df['Percent_Rain'] = json_df['RainProbability'] json_df['Percent_Snow'] = json_df['SnowProbability'] json_df[['Date','Time']] = json_df['DateTime'].str.split('T', expand=True) # trim the time to hh:mm format, change to str json_df[['Time']] = json_df['Time'].str.split('+', expand=True)[0].astype(str).str[:5] current_retrieved_datetime = str(json_df['Date'][0])+' '+str(json_df['Time'][0]) rain_msg="" snow_msg="" # check % Rain column, return rain_msg json_df.loc[json_df['Percent_Rain'] >= RAIN_THRESHOLD, 'Rain_Alert'] = 1 json_df.loc[json_df['Percent_Rain'] < RAIN_THRESHOLD, 'Rain_Alert'] = 0 if (sum(json_df['Rain_Alert']) > 0): rain_msg = 'There is ' \ +str(json_df['Percent_Rain'][json_df['Rain_Alert']==1][0]) \ +' % chance of rain' \ +' at ' \ +str(json_df['Time'][json_df['Rain_Alert']==1][0]) # check % Snow column json_df.loc[json_df['Percent_Snow'] >= SNOW_THRESHOLD, 'Snow_Alert'] = 1 json_df.loc[json_df['Percent_Snow'] < SNOW_THRESHOLD, 'Snow_Alert'] = 0 if (sum(json_df['Snow_Alert']) > 0): snow_msg = 'There is ' \ +str(json_df['Percent_Snow'][json_df['Percent_Snow']==1][0]) \ +' % chance of snow' \ +' at ' \ +str(json_df['Time'][json_df['Percent_Snow']==1][0]) alert_msg ="" if(len(rain_msg)|len(snow_msg)!=0): alert_msg = rain_msg +" "+snow_msg link_for_click = json_df['MobileLink'][0] return(current_retrieved_datetime,alert_msg,link_for_click)
4. Автоматизированная петля
Наконец, для последней части мы автоматизируем процесс с помощью петлей. Приведенные ниже скрипты помещают количество петель как «.
num_repeat = 999 # number of loops to repeat previous_alert_msg = "" # initialize alert msg
Используйте попытку, кроме преодоления ошибок (на случай, если что-то пойдет не так с подключениями). Вызовите функцию func_get_weather и назначить переменные.
for i in range(num_repeat): try: current_retrieved_datetime,alert_msg,link_for_click = func_get_weather(url_page) except (RuntimeError, TypeError, NameError, ValueError, urllib.error.URLError): print('error catched')
Затем проверьте, есть ли какие-либо изменения в погоде. Если ничего не изменилось, распечатайте сообщение на экран. Не будет отправлено сообщение об чате.
#if the weather forecast has not changed, no alert msg will be sent if len(alert_msg) > 0 and previous_alert_msg == alert_msg: print(i, current_retrieved_datetime, 'no changes in weather forecast')
Сообщение будет отправлено только в том случае, если есть какие-либо изменения в погоде.
Мы можем доработать наше сообщение в этот момент. Получить свой идентификатор пользователя своих друзей и храните в «Friend_List». Цикл, чтобы отправить сообщение каждому другу односторонню. Мы помещаем секунды сна между каждым сообщением и выходом после завершения.
if len(alert_msg) > 0 and previous_alert_msg != alert_msg: # login and send facebook msg client = Client(FB_USERNAME,FB_PASSWORD) users = client.fetchAllUsers() friend_list=[user.uid for user in users if user.uid!="0"] # loop though all friends for id in friend_list: client.send(Message(text=current_retrieved_datetime+' '+'12-hr Weather Forecast' +' '+ alert_msg +' '+link_for_click),thread_id=id, thread_type=ThreadType.USER) #sleep for 2 secs between each msg time.sleep(2) #logout after sent client.logout()
Выполните время задержки для следующего сообщения. Уже определено в paramspy Файл – в этом случае это 4 часа. И еще один для задержки запроса на Accuweather составляет 1 час.
time.sleep(delay_time_sec) time.sleep(update_interval_sec)
Опять же, не волнуйтесь, если вы потерялись. Я поставил полный цикл вместе ниже.
# Execute functions, retrieve data and send facebook msg num_repeat = 999 # number of loops to repeat previous_alert_msg = "" # initialize alert msg for i in range(num_repeat): try: current_retrieved_datetime,alert_msg,link_for_click = func_get_weather(url_page) except (RuntimeError, TypeError, NameError, ValueError, urllib.error.URLError): print('error catched') #if the weather forecast has not changed, no alert msg will be sent if len(alert_msg) > 0 and previous_alert_msg == alert_msg: print(i, current_retrieved_datetime, 'no changes in weather forecast') #if there is any changes in weather if len(alert_msg) > 0 and previous_alert_msg != alert_msg: # login and send facebook msg client = Client(FB_USERNAME,FB_PASSWORD) users = client.fetchAllUsers() friend_list=[user.uid for user in users if user.uid!="0"] # loop though all friends for id in friend_list: client.send(Message(text=current_retrieved_datetime+' '+'12-hr Weather Forecast' +' '+ alert_msg +' '+link_for_click),thread_id=id, thread_type=ThreadType.USER) #sleep for 2 secs between each msg time.sleep(2) #logout after sent client.logout() time.sleep(delay_time_sec) time.sleep(update_interval_sec) print(current_retrieved_datetime,'Run Completed')
Та-да! После всей нашей тяжелой работы, вот снимок сообщения, которое мы получим.
Если нам нужно знать более подробно, мы можем напрямую щелкнуть по ссылке. Он будет переходить на мобильный веб-сайт Accuweather.
Заполненный скрипт для этого как – это тоже Документировано на Github Отказ
Спасибо за чтение. Пожалуйста, попробуйте, повеселиться и дайте мне знать ваши отзывы!
Если вам понравится то, что я сделал, подумайте о том, чтобы следовать за мной Github , Средний и Twitter Отказ Убедитесь, что чтобы звездить на Github : D.