[PYTHON] Ich habe einen SlackBot erstellt, der mich jede Woche über Informationen zum AtCoder-Wettbewerb informiert

AtCoder-Wettbewerbsinformationen Wir haben einen Slackbot erstellt, um AtCoder-Wettbewerbsinformationen zu benachrichtigen.

(1) Erhalten des Bot-API-Tokens und Installieren des Slackbot

Sie müssen ein API-Token erhalten und slackbot installieren, bevor Sie einen Slackbot erstellen können. Diese beiden werden in SlackBot-Entwicklung mit Python ① "API-Schlüssel und einfache Antwort abrufen" beschrieben. Ich habe das einfach gemacht. Wenn Sie wie geschrieben ausführen und im Gespräch mit Bot eine entsprechende Zeichenfolge senden, wird der in DEFALUT_REPLY festgelegte Wortlaut wie unten gezeigt zurückgegeben. スクリーンショット 2019-11-13 16.13.20.png

(2) Web Scraping

Da ich bestätigt habe, dass Slackbot funktioniert, werde ich AtCoder-Wettbewerbsinformationen kratzen und sammeln. Unten ist der Code.

scrape.py



from urllib import request
from bs4 import BeautifulSoup
import re
import datetime


#Gibt ein Zeit / URL-Paar zurück
def scrape_active():
    '''
Eine Funktion, die Informationen über den aktuell stattfindenden Wettbewerb zurückgibt
    '''
    re_contests=[]
    #Erhalten Sie Informationen zu dieser URL
    url="https://atcoder.jp"
    html=request.urlopen(url)
    #Analysieren Sie Seiteninformationen mit dem Parser
    soup=BeautifulSoup(html, "html.parser")
    #contest-table-Informationen zum aktuell stattfindenden Wettbewerb sind im div-Tag mit der ID active enthalten
    contests1=soup.find("div",id="contest-table-active")
    #Wenn es keinen Wettbewerb gibt(Weil keiner in der Suppe enthalten sein wird)
    if contests1 is None:
        return re_contests
    contests2=contests1.find("tbody")
    contests3=contests2.find_all("tr")
    #re_Speichern Sie die URL des Wettbewerbs sowie das Enddatum und die Endzeit der Wettbewerbe
    for c in contests3:
        re_contests_sub=[]
        #Speichern Sie die URL der Wettbewerbsseite in url2
        d=c.find("a",href=re.compile("contests"))
        url2=url+d.get("href")
        html2=request.urlopen(url2)
        soup2=BeautifulSoup(html2, "html.parser")
        #Klasse ist ein reserviertes Wort in Python, also Klasse_
        sftime=soup2.find_all("time",class_="fixtime-full")
        #Re nur die Endzeit_contests_In Unter speichern
        re_contests_sub.append(sftime[1]+"Ende")
        #Die URL der Wettbewerbsseite ist ebenfalls neu_contests_In Unter speichern
        re_contests_sub.append(url2)
        re_contests.append(re_contests_sub)
    return re_contests


def scrape_upcoming():
    '''
Eine Funktion, die Informationen zu Wettbewerben zurückgibt, die innerhalb einer Woche stattfinden
    '''
    re_contests=[]
    url="https://atcoder.jp"
    html = request.urlopen(url)
    soup = BeautifulSoup(html, "html.parser")
    #contest-table-Informationen zu Wettbewerben, die innerhalb einer Woche stattfinden sollen, sind im div-Tag mit der ID des bevorstehenden Wettbewerbs enthalten
    contests1=soup.find("div",id="contest-table-upcoming")
    #Wenn es keinen Wettbewerb gibt(Weil keiner in der Suppe enthalten sein wird)
    if contests1 is None:
        return re_contests
    contests2=contests1.find("tbody")
    contests3=contests2.find_all("tr")
    #Holen Sie sich das heutige Datum und die Uhrzeit(Montag)
    w=datetime.datetime.today()
    #Überprüfen Sie die URL und das Startdatum und die Startzeit des Wettbewerbs_In Wettbewerben speichern
    for c in contests3:
        re_contests_sub=[]
        d1=c.find("time")
        #Schneiden und übergeben Sie nur den Teil, der bis zur Minute enthält
        #Rückkehr vom String zum datetime-Objekt mit der Funktion strtotime
        t=strtotime(d1.text[:16])
        #Sie müssen keine Wettbewerbe speichern, die nicht bis Sonntag der Woche stattfinden
        if (t-w).days>=7:
            break
        #Verwenden Sie die Funktion timetostr, um das Format zu vereinheitlichen
        #Speichern Sie das Startdatum und die Startzeit des Wettbewerbs
        re_contests_sub.append(timetostr(t)+"Start")
        d2=c.find("a",href=re.compile("contests"))
        #Die URL der Wettbewerbsseite ist ebenfalls neu_contests_In Unter speichern
        re_contests_sub.append(url+d2.get("href"))
        re_contests.append(re_contests_sub)
    return re_contests

def strtotime(date_sub):
    '''
Rückgabe als Datum / Uhrzeit-Objekt
    '''
    return datetime.datetime.strptime(date_sub,'%Y-%m-%d %H:%M')

def timetostr(date_sub):
    '''
Gibt ein datetime-Objekt als str-Objekt zurück
    '''
    W=["Mond","Feuer","Wasser","Holz","Geld","Boden","Tag"]
    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")
    ))

Ich habe in dem Kommentar geschrieben, was ich tue, aber wenn Sie Fragen zur Verwendung der Funktion haben, lesen Sie bitte die Seite, auf die Sie verwiesen haben.

Referenzierte Seite

Zusammenfassung der Grundlagen des Schabens bei Beautiful Soup [für Anfänger] Grundlagen der schönen Suppe + Anfragen Python-Datumstyp datetime

(3) Buchung auf Slack

Wir werden die gesammelten Wettbewerbsinformationen an Slack senden.

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_Senden Sie eine Nachricht mit messag.
    '''
    for i in s:
        message=message+"\n"+i[0]+"\n"+i[1]+"\n"
    #pos_Sie können mit Nachricht nachlassen
    #Kanal, den Sie auf Kanal posten möchten
    #Die Nachricht, die Sie in der Nachricht veröffentlichen möchten
    #as_Wenn Sie den Benutzer auf True setzen, wird die URL erweitert und veröffentlicht.
    slack.chat.post_message(channel, message, as_user=True)

def info(channel,slack):
    #Zuerst kratzen, um Wettbewerbsinformationen zu speichern
    s1=scrape.scrape_active()
    s2=scrape.scrape_upcoming()
    #Keine Wettbewerbsinformationen(0 in der Länge)Senden Sie eine Nachricht, dass der Wettbewerb nicht existiert
    if len(s1)!=0:
        make_message(channel,slack,s1,"*[Liste der Wettbewerbe]*")
    else:
        slack.chat.post_message(channel,"*Es finden keine Wettbewerbe statt*",as_user=True)
    if len(s2)!=0:
        make_message(channel,slack,s2,"*[Die Wettbewerbsliste dieser Woche]*")
    else:
        slack.chat.post_message(channel,"*Diese Woche gibt es keinen Wettbewerb*",as_user=True)

def main():
    #Vergessen Sie nicht, die Bot-Anwendung zu diesem Kanal hinzuzufügen, bevor Sie den Bot ausführen
    channel="Competitive Pro"
    #API-Token ist Slackbot_settings.Speichern, um zu py
    slack = Slacker(slackbot_settings.API_TOKEN)
    #Bestätigung, dass es Montag ist
    if datetime.datetime.today().weekday()==0:
        info(channel,slack)
    bot = Bot()
    bot.run()

if __name__ == "__main__":
    main()

Siehe Auskommentieren wie in (2). (Weil es lang und schwer zu lesen wird, wenn es ausführlich erklärt wird)

Referenzierte Seite

chat.postMessage Die Geschichte, dass die URL in Slacks Incoming Webhooks veröffentlicht wurde, wurde nicht erweitert Erstellen eines Bots mit Slack API 2: Nachrichtenposting

(4) In Heroku bereitstellen

Bis zu (3) sollten Sie es lokal ausführen können, indem Sie auf "python run.py" klicken. Als nächstes in Heroku bereitstellen. (Heroku ist wie ein kostenloser Server) Heroku selbst ist nicht schwer zu handhaben, wenn Sie es als Remote-Repository für Git betrachten. Wenn Sie also Git studieren, sollten Sie wissen, wie man es verwendet. (Progates Git-Kapitel wird als Ganzes empfohlen.) Außerdem werde ich die Datei mit Git an Heroku senden, aber wie im Referenzartikel beschrieben, erstellen wir drei Dateien: Procfile, require.txt, runtime.txt und drücken dann. .. (Wenn Sie es nicht erstellen, werden verschiedene Fehler ausgespuckt und es ist leer.)

Referenzierte Seite

Slackbot in Python erstellen Hinweise zum Erstellen von SlackBot mit Python-Resident

(5) Einstellen von Umgebungsvariablen

Wenn Sie dem in (1) genannten Artikel folgen, sollte eine Datei mit dem Namen slackbot_settigns erstellt und zwei Variablen, API_TOKEN und DEFAULT_REPLY, definiert werden. Wenn dies jedoch unverändert bleibt, wird der Token-Wert erhalten, wenn der Quellcode leckt, und der Bot wird entführt. Daher muss er als Umgebungsvariable verwendet werden, ohne den Token-Wert in den Quellcode zu schreiben. Lokal können Sie den Befehl "Umgebungsvariablenname = Wert exportieren" eingeben. Wenn Sie jedoch die Heroku-Umgebungsvariable festlegen möchten, legen Sie die Umgebungsvariable fest, indem Sie "Heroku-Konfiguration: Umgebungsvariablenname = Wert" festlegen. Ich kann es schaffen Sie können Umgebungsvariablen auch in Config Vars of Settings der entsprechenden Anwendung in Heroku festlegen. Auf diese Weise können Sie die Umgebungsvariablen festlegen und durch Umschreiben von slackbot_settigns wie unten gezeigt die Einstellungen für Umgebungsvariablen vervollständigen.

slackbot_settings.py


import os

#Umgebungsvariablen abrufen
API_TOKEN=os.environ["API_TOKEN"]
DEFAULT_REPLY=os.environ["DEFAULT_REPLY"]

Informationen zur Verwendung von os.environ finden Sie unter Abrufen / Hinzufügen / Überschreiben / Löschen von Umgebungsvariablen mit Python (os.environ). Bitte gib mir.

Referenzierte Seite

[Python] So stellen Sie ein Python-Programm für Heroku bereit → Außerdem wird die Verwendung von Heroku beschrieben.

(6) Scheduler-Registrierung

Wenn Sie den Scheduler endgültig registrieren, ist die gesamte Automatisierung abgeschlossen. Zuerst füge ich einen Scheduler als Add-On hinzu, muss aber eine Kreditkarte registrieren. Stellen Sie sicher, dass Sie sich auf der Kontoseite registrieren. Nach der Registrierung können Sie den Scheduler mit "$ heroku addons: create scheduler: standard" zum Add-on hinzufügen und die Registrierungsseite für den Scheduler mit "heroku addons: open scheduler" öffnen. Wenn Sie auf der geöffneten Seite auf "Job hinzufügen" klicken, können Sie ihn regelmäßig ausführen, indem Sie das zu verschiebende Zeitintervall und den Befehl registrieren, den Sie ausführen möchten. (Wenn Sie es ausführen, ohne es im Scheduler zu registrieren, wird es übrigens etwa alle 6 Stunden ausgeführt.) In meinem Fall wollte ich es auch einmal pro Woche ausführen, also habe ich es so geändert, dass es jeden Tag ausgeführt wird und das Programm die gewünschte Verarbeitung nur einmal pro Woche ausführt. (Beachten Sie auch, dass die Zeit in UTC angegeben ist. Sie müssen also neun Stunden zur UTC-Zeit hinzufügen, um sie in japanische Zeit umzurechnen.)

Referenzierte Seite

SlackBot-Entwicklung mit Python ⑧ "Periodische Programmausführung mit Heroku Scheduler"

Recommended Posts

Ich habe einen SlackBot erstellt, der mich jede Woche über Informationen zum AtCoder-Wettbewerb informiert
Ich habe einen schlaffen Bot gemacht, der mich über die Temperatur informiert
Ich habe einen Linebot erstellt, der mich über nahegelegene Evakuierungsstellen auf AWS informiert
[Atcoder] [C ++] Ich habe ein Testautomatisierungstool erstellt, das während des Wettbewerbs verwendet werden kann
Ich habe einen Kalender erstellt, der den Verteilungsplan von Vtuber automatisch aktualisiert
Nachdem ich Python3 studiert hatte, machte ich einen Slackbot
Ich habe einen Slack-Bot geschrieben, der Verzögerungsinformationen mit AWS Lambda benachrichtigt
Ich habe einen LINE-Bot erstellt, der jeden Tag pünktlich empfohlene Bilder sendet
Mit LINEBot habe ich eine Anwendung erstellt, die mich über die "Buszeit" informiert.
[Bot dekodieren] Ich habe versucht, einen Bot zu erstellen, der mir den Rassenwert von Pokemon angibt
In Python habe ich einen LINE-Bot erstellt, der Polleninformationen aus Standortinformationen sendet.
Ich habe eine Twitter-App erstellt, die die Zeichen der Vorverbindung mit Heroku entschlüsselt (Fehler).
Erstellt eine Web-App, die IT-Ereignisinformationen mit Vue und Flask abbildet
[Python / C] Ich habe versucht, ein Gerät zu erstellen, das den Bildschirm eines PCs drahtlos aus der Ferne scrollt.
Ich habe einen Kalender erstellt, der den Verteilungsplan von Vtuber automatisch aktualisiert (Google Kalender Edition).
Ich habe ein Schwellenwertänderungsfeld für Peppers Dialog erstellt
Eine Geschichte, die stolperte, als ich mit Transformer einen Chat-Chat-Bot erstellte
AtCoder Anfängerwettbewerb 166 A Erklärung des Problems "A? C" (Python3, C ++, Java)
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen
Ich habe eine verdammte App gemacht, mit der du nicht überspringen kannst
AtCoder Grand Contest 046: A --Takahashikun, The Strider Animationszeichnung
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 1)
Ich habe einen harten Pomodoro-Timer entwickelt, der mit CUI funktioniert
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 2)
Ich habe ein Plug-In erstellt, das "Daruma-san Fell" mit Minecraft ausführen kann
Ich habe einen neuronalen Netzwerkgenerator erstellt, der auf FPGA läuft
Ich habe versucht, eine Site zu erstellen, mit der die aktualisierten Informationen von Azure einfach angezeigt werden können
Ich habe einen Linienbot erstellt, der das Geschlecht und das Alter einer Person anhand des Bildes errät
Ich habe mit Heroku + Flask + PostgreSQL (Heroku Postgres) einen LINE-Bot erstellt, der mir den Typ und die Stärke von Pokemon in der Garal-Region angibt.