Informations sur le concours AtCoder Nous avons créé un Slackbot pour notifier les informations sur le concours AtCoder.
Vous devez obtenir un jeton API et installer slackbot avant de pouvoir créer un Slackbot. Ces deux éléments sont décrits dans Développement SlackBot avec Python ① "Obtenir la clé API et la réponse simple" Je viens de faire ça. Si vous exécutez comme écrit et envoyez une chaîne de caractères appropriée en conversation avec Bot, le libellé défini dans DEFALUT_REPLY sera renvoyé comme indiqué ci-dessous.
Depuis que j'ai confirmé que Slackbot fonctionne, je vais gratter et collecter les informations du concours AtCoder. Ci-dessous le code.
scrape.py
from urllib import request
from bs4 import BeautifulSoup
import re
import datetime
#Renvoie une paire heure / URL
def scrape_active():
'''
Une fonction qui renvoie des informations sur le concours en cours
'''
re_contests=[]
#Recevoir des informations sur cette URL
url="https://atcoder.jp"
html=request.urlopen(url)
#Analyser les informations de la page avec un analyseur
soup=BeautifulSoup(html, "html.parser")
#contest-table-Les informations sur le concours en cours sont incluses dans la balise div avec l'identifiant d'actif
contests1=soup.find("div",id="contest-table-active")
#S'il n'y a pas de concours(Parce qu'aucun ne sera inclus dans la soupe)
if contests1 is None:
return re_contests
contests2=contests1.find("tbody")
contests3=contests2.find_all("tr")
#re_Enregistrer l'URL du concours et la date et l'heure de fin des concours
for c in contests3:
re_contests_sub=[]
#Stocker l'url de la page du concours dans url2
d=c.find("a",href=re.compile("contests"))
url2=url+d.get("href")
html2=request.urlopen(url2)
soup2=BeautifulSoup(html2, "html.parser")
#class est un mot réservé en Python, donc class_
sftime=soup2.find_all("time",class_="fixtime-full")
#Re seulement le temps de la fin_contests_Stocker en sous
re_contests_sub.append(sftime[1]+"Fin")
#L'url de la page du concours est également re_contests_Stocker en sous
re_contests_sub.append(url2)
re_contests.append(re_contests_sub)
return re_contests
def scrape_upcoming():
'''
Une fonction qui renvoie des informations sur les concours organisés dans une semaine
'''
re_contests=[]
url="https://atcoder.jp"
html = request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
#contest-table-Les informations sur les concours qui auront lieu dans une semaine sont incluses dans la balise div avec l'identifiant du prochain
contests1=soup.find("div",id="contest-table-upcoming")
#S'il n'y a pas de concours(Parce qu'aucun ne sera inclus dans la soupe)
if contests1 is None:
return re_contests
contests2=contests1.find("tbody")
contests3=contests2.find_all("tr")
#Obtenir la date et l'heure du jour(Lundi)
w=datetime.datetime.today()
#Re l'url et la date et l'heure de début du concours_Stocker dans les concours
for c in contests3:
re_contests_sub=[]
d1=c.find("time")
#Trancher et passer uniquement la partie qui contient jusqu'à la minute
#Retour d'une chaîne à un objet datetime avec la fonction strtotime
t=strtotime(d1.text[:16])
#Vous n'avez pas à stocker les concours qui ne sont pas le dimanche de la semaine
if (t-w).days>=7:
break
#Utilisez la fonction timeostr pour unifier le format
#Stocker la date et l'heure de début du concours
re_contests_sub.append(timetostr(t)+"début")
d2=c.find("a",href=re.compile("contests"))
#L'url de la page du concours est également re_contests_Stocker en sous
re_contests_sub.append(url+d2.get("href"))
re_contests.append(re_contests_sub)
return re_contests
def strtotime(date_sub):
'''
Retour en tant qu'objet datetime
'''
return datetime.datetime.strptime(date_sub,'%Y-%m-%d %H:%M')
def timetostr(date_sub):
'''
Renvoie un objet datetime en tant qu'objet str
'''
W=["Mois","Feu","eau","bois","Argent","sol","journée"]
return ('%d-%d-%d(%s) %d:%s'%(
date_sub.year,date_sub.month,date_sub.day,W[date_sub.weekday()],date_sub.hour,str(date_sub.minute).ljust(2,"0")
))
J'ai écrit ce que je fais dans le commentaire, mais si vous avez des questions sur l'utilisation de la fonction, veuillez consulter la page à laquelle vous avez fait référence.
Résumé des bases du grattage à Beautiful Soup [pour les débutants] Bases de Beautiful Soup + Requests Type de date Python datetime
Nous publierons les informations collectées sur le concours sur Slack.
run.py
from slackbot.bot import Bot
from slacker import Slacker
import slackbot_settings
import scrape
import datetime
def make_message(channel,slack,s,message):
'''
slack.chat.post_Envoyez un message en utilisant la messagerie.
'''
for i in s:
message=message+"\n"+i[0]+"\n"+i[1]+"\n"
#pos_Vous pouvez publier sur Slack avec un message
#Chaîne que vous souhaitez publier sur la chaîne
#Le message que vous souhaitez publier dans le message
#as_En définissant l'utilisateur sur True, l'URL sera développée et publiée.
slack.chat.post_message(channel, message, as_user=True)
def info(channel,slack):
#Grattez d'abord pour stocker les informations du concours
s1=scrape.scrape_active()
s2=scrape.scrape_upcoming()
#Aucune information sur le concours(0 de longueur)Envoyez un message indiquant que le concours n'existe pas
if len(s1)!=0:
make_message(channel,slack,s1,"*[Liste des concours organisés]*")
else:
slack.chat.post_message(channel,"*Aucun concours n'est organisé*",as_user=True)
if len(s2)!=0:
make_message(channel,slack,s2,"*[Liste des concours de cette semaine]*")
else:
slack.chat.post_message(channel,"*Il n'y a pas de concours cette semaine*",as_user=True)
def main():
#N'oubliez pas d'ajouter l'application Bot à ce canal avant d'exécuter le Bot
channel="Pro compétitif"
#Le jeton API est slackbot_settings.Enregistrer dans py
slack = Slacker(slackbot_settings.API_TOKEN)
#Confirmation que c'est lundi
if datetime.datetime.today().weekday()==0:
info(channel,slack)
bot = Bot()
bot.run()
if __name__ == "__main__":
main()
Voir commenter comme dans (2). (Parce que cela devient long et difficile à lire si expliqué en détail)
chat.postMessage L'histoire selon laquelle l'URL publiée sur les Webhooks entrants de Slack n'a pas été développée Création d'un bot avec Slack API 2: publication de messages
Jusqu'à (3), vous devriez pouvoir l'exécuter localement en appuyant sur python run.py
. Ensuite, déployez sur Heroku. (Heroku est comme un serveur gratuit)
Heroku lui-même n'est pas difficile à gérer si vous le considérez comme un dépôt distant pour Git, donc si vous étudiez Git, vous devriez savoir comment l'utiliser. (Le chapitre Git de Progate est recommandé dans son ensemble.)
De plus, je vais pousser le fichier vers Heroku en utilisant Git, mais comme décrit dans l'article de référence, créons trois fichiers, Procfile, requirements.txt, runtime.txt, puis push. .. (Si vous ne le créez pas, diverses erreurs seront crachées et il sera vide.)
Créer Slackbot en Python Notes sur la création de SlackBot avec un résident python
Si vous suivez l'article mentionné dans (1), un fichier appelé slackbot_settigns doit être créé et deux variables, API_TOKEN et DEFAULT_REPLY, doivent être définies.
Cependant, si cela reste tel quel, la valeur du jeton sera obtenue lorsque le code source fuit et le Bot sera détourné, il est donc nécessaire de l'utiliser comme variable d'environnement sans écrire la valeur du jeton dans le code source.
Localement, vous pouvez taper la commande ʻexport environment variable name = value, mais si vous voulez définir la variable d'environnement heroku, définissez la variable d'environnement en définissant
heroku config: set environment variable name = value`. Je peux le faire. Vous pouvez également définir des variables d'environnement dans Config Vars ou Settings de l'application correspondante dans Heroku.
Cela vous permet de définir des variables d'environnement et la réécriture de slackbot_settigns comme indiqué ci-dessous complète les paramètres des variables d'environnement.
slackbot_settings.py
import os
#Obtenir des variables d'environnement
API_TOKEN=os.environ["API_TOKEN"]
DEFAULT_REPLY=os.environ["DEFAULT_REPLY"]
Pour savoir comment utiliser os.environ, reportez-vous à Get / Add / Overwrite / Delete Environment Variables with Python (os.environ). S'il te plait donne moi.
[Python] Comment déployer un programme Python sur Heroku → Il décrit également comment utiliser Heroku.
Lorsque vous enregistrez enfin le planificateur, toute l'automatisation est terminée.
Tout d'abord, j'ajoute un planificateur en tant que module complémentaire, mais je dois enregistrer une carte de crédit. Assurez-vous de vous inscrire à partir de la page du compte.
Après vous être enregistré, vous pouvez ajouter le planificateur au module complémentaire avec $ heroku addons: create scheduler: standard
, et vous pouvez ouvrir la page pour vous inscrire avec le planificateur avec heroku addons: open scheduler
.
Si vous appuyez sur "Ajouter un travail" sur la page ouverte, vous pouvez l'exécuter régulièrement en enregistrant l'intervalle de temps pour se déplacer et la commande que vous souhaitez exécuter. (À propos, si vous l'exécutez sans l'enregistrer dans le planificateur, il sera exécuté environ toutes les 6 heures.)
De plus, dans mon cas, je voulais l'exécuter une fois par semaine, alors je l'ai changé pour qu'il s'exécute tous les jours et que le programme n'effectue le traitement souhaité qu'une fois par semaine. (En outre, veuillez noter que l'heure est exprimée en UTC, vous devez donc ajouter 9 heures à l'heure UTC pour la convertir en heure japonaise.)
Développement SlackBot avec Python ⑧ "Exécution périodique du programme avec Heroku Scheduler"
Recommended Posts