L'histoire de la création d'un robot LINE pour le petit-déjeuner d'une université de 100 yens avec Python

Cet article est le premier jour du calendrier de l'Avent 2019 de l'Université de la ville de Tokyo. https://adventar.org/calendars/4282

introduction

salut! Je m'appelle Ojie (@ 920oj) et j'étudie les systèmes d'information dans une université appelée Tokyo City University. Cette fois, j'ai construit un calendrier de l'Avent de la taille d'une ville, alors je J'écrirai "L'histoire de la création d'un bot LINE qui vous informe d'un petit-déjeuner de 100 yens à l'université avec Python"!

Contexte

Notre école dispose d'un système très rentable où vous pouvez prendre votre petit-déjeuner pour 100 yens. De plus, comme je vis seul à Tokyo dans une zone rurale, c'est parfait pour manquer d'argent.

image.png

C'est 100 yens

Ce menu est affiché sur le site Web de la cafétéria tous les matins, mais ce site Web est un auteur-compositeur et vous devez passer par l'application ou le site portail de l'école pour y accéder.

Par conséquent, j'ai décidé de gratter automatiquement le site Web de la cafétéria chaque matin et de créer une notification LINE qui informera LINE du petit-déjeuner de 100 yens de la journée.

Environnement de l'écrivain

Python v3.7.1 pip 19.1.1 Windows 10 v1903

Ce qui a été fait

Cafétéria des étudiants du campus de Yokohama de l'université de la ville de Tokyo Bot de notification de petit-déjeuner de 100 yens https://github.com/920oj/TCU-YC-Breakfast-Notify-Bot

image.png

Ainsi, vous serez averti tous les jours à 7h30 du matin (uniquement si vous prenez un petit-déjeuner à 100 yens)!

Pensez à la mise en œuvre

Tout d'abord, accédez au site Web de l'alimentation scolaire avec Beautiful Soup. Puisque vous devez vous connecter pour parcourir le site Web de l'alimentation scolaire, nous avons établi une directive pour lancer un POST une fois pour vous authentifier, puis pétrir à l'aide de l'identifiant de session.

Cependant, si vous regardez de plus près, l'authentification n'existe pas et il semble que vous écrivez simplement l'ID et le mot de passe en texte brut dans le cookie pour vous authentifier. (C'est OK?)

(À l'origine, une fois authentifié (POST), l'ID de session est lié au fait que l'authentification a réussi et que les demandes suivantes sont acceptées, mais pour une raison quelconque, cela fonctionne sans POST. C'est bien parce que c'est bon) (Ce n'est pas bon à l'origine)

Relation de session

Pour le moment, lorsque vous allez sur la page de connexion, il semble qu'une "clé de session" et un "identifiant de session" soient donnés, donc il commence par l'obtenir.

def get_sessionid():
    #Processus initial d'acquisition des cookies
    r = requests.get('https://livexnet.jp/local/default.asp')
    first_access_cookie = str(r.headers['Set-Cookie'])
    
    # "ASPSESSIONID+Toute capitale anglaise à 8 chiffres"(24 caractères alphabétiques)Avoir
    asp_session = str(first_access_cookie[first_access_cookie.find("ASPSESSIONID"):first_access_cookie.find("; secure")])
    asp_session_key = str(asp_session[0:asp_session.find("=")])
    asp_session_id = str(asp_session[asp_session.find("="):].replace('=',''))
    return asp_session_key, asp_session_id

Le framework est comme ASP.NET. En ce qui concerne ASPSESSIONID, il semble qu'une majuscule à 8 chiffres soit ajoutée à la fin, alors obtenez-la également. Les valeurs de retour de cette fonction sont asp_session_key et asp_session_id, et deux types sont renvoyés.

Définir le raclage des cookies

def get_breakfast_info(key,id):
    #Préparer les cookies (les informations peuvent changer à l'avenir)
    site_cookies = {
        key: id, 
        'KCD': '02320', 
        'company_id': SITE_ID, 
        'company_pw': SITE_PASS, 
        'wrd': 'jp', 
        'dip': '0', 
        'ink': 'a', 
        'bcd': '02320', 
        'val': 'daily'
    }
    
    #Accéder au menu / à la page du tableau nutritionnel
    url = 'https://reporting.livexnet.jp/eiyouka/menu.asp?val=daily&bcd=02320&ink=a&col=&str=' + today_data
    r = requests.get(url, cookies=site_cookies)
    r.encoding = r.apparent_encoding
    
    #Analyse HTML
    all_html = r.text.replace('<br>','')
    souped_html = BeautifulSoup(all_html, 'lxml')
    
    try:
        breakfast = souped_html.find('p', class_="img_comment6").string
        return breakfast
    except:
        return False

Utilisez les outils de développement de Chrome pour voir quels cookies sont définis.

Après vérification, préparez un cookie en fonction de celui-ci et chargez-le dans beautifulsoup, alors préparez un dictionnaire.

La clé est la clé de session obtenue précédemment et l'ID est l'ID de session. (Ce n'est pas le nom de la variable. Rendons-le plus descriptif)

Comme mentionné précédemment, il semble que l'ID d'authentification et le mot de passe soient lus en texte brut avec SITE_ID et SITE_PASS (?), Alors spécifiez-le tel quel.

(N'est-il pas inutile d'obtenir cet identifiant de session ...? S'il vous plaît laissez-moi savoir si vous avez des détails.)

Tout ce que vous avez à faire est de le charger dans lxml, qui analyse le HTML, et d'en extraire l'élément de classe "img_comment6"!

image.png

Aller à LINE (LINE Notify)

def post_line(result):
    post_data = 'aujourd'hui(' + today_data + ')100 yens petit-déjeuner' + result + 'est.'
    
    line_api_headers = {"Authorization" : "Bearer "+ LINE_TOKEN}
    line_payload = {"message" :  post_data}
    
    r = requests.post(LINE_API_URL ,headers = line_api_headers ,params=line_payload)
    return r.status_code

Tout ce que vous avez à faire est de passer à LINE Notify. Avec LINE Notify, vous pouvez mettre les informations d'authentification et le contenu du message dans l'en-tête et lancer POST au point de terminaison de l'API pour envoyer les informations à la conversation prédéfinie.

Écrivez le processus principal

def main():
    print('Programme d'affichage du menu du petit-déjeuner à 100 yens de l'Université de la ville de Tokyo')
    print('aujourd'hui' + today_data + 'est.')
    
    session = get_sessionid()
    session_key = session[0]
    session_id = session[1]
    
    print('Obtention des informations d'identification initiales.' + session_key + 'Est' + session_id + 'est. Attendez 3 secondes ...')
    sleep(3)
    
    result = get_breakfast_info(session_key,session_id)
    
    if not result:
        print('Aucune information n'a pu être obtenue. 100 yens Le petit-déjeuner peut ne pas être disponible.')
        sys.exit()

    print('Le petit-déjeuner de 100 yens d'aujourd'hui est' + result + 'est. Envoyez une notification à LINE.')
    
    post_status = post_line(result)
    if post_status == 200:
        print('La notification LINE a réussi. Quittez le programme.')
    else:
        print('La notification LINE a échoué. La réponse est' + str(post_status) + 'est. Quittez le programme.')
    
if __name__ == "__main__":
    main()

Après cela, j'écrirai le processus principal de la même manière que l'assemblage de la fonction créée précédemment.

Enfin, écrivez ʻif name == "main": `pour éviter que le processus ne soit exécuté arbitrairement si ce programme est importé quelque part. Je n'ai jamais entendu parler d'un mécanisme qui appelle la fonction main () lorsque les noms des fichiers en cours d'exécution correspondent.

fonctionner

Je l'héberge sur mon Lightsail (VPS) emprunté et je l'exécute régulièrement avec cron. Dès que je le lance, je vais prendre le petit-déjeuner de la journée, donc je lance cron tous les matins à 7h30 pour réaliser une exécution régulière.

finalement

Pour dire la vérité, ce code a été créé en avril, donc quand je le regarde maintenant, il y a des endroits où les noms de variables ne sont pas corrects et l'implémentation est ambiguë. J'aimerais réécrire le code quand j'aurai un peu plus de temps libre.


Demain est un article de M. K (@ ke_odakyu9000)! Ravi de vous rencontrer! https://adventar.org/calendars/4282

Recommended Posts

L'histoire de la création d'un robot LINE pour le petit-déjeuner d'une université de 100 yens avec Python
L'histoire de la création d'un bot de boîte à questions avec discord.py
L'histoire de la création d'un pilote standard pour db avec python.
L'histoire de la création d'un module qui ignore le courrier avec python
L'histoire de la création d'un Line Bot qui nous raconte le calendrier de la programmation du concours
L'histoire de la mise en œuvre du sujet Facebook Messenger Bot avec python
L'histoire du traitement A du blackjack (python)
Mathématiques Todai 2016 résolues avec Python
Créer un LINE BOT avec Minette pour Python
L'histoire de la création d'une caméra sonore avec Touch Designer et ReSpeaker
L'histoire de la création d'un générateur d'icônes mel
L'histoire de la création d'un Bot qui affiche les membres actifs dans un canal spécifique de Slack avec Python
L'histoire de la création d'un outil pour charger une image avec Python ⇒ l'enregistrer sous un autre nom
L'histoire de la création d'une application Web qui enregistre des lectures approfondies avec Django
L'histoire de la création d'un réseau neuronal de génération musicale
L'histoire de la création d'une partition de type Hanon avec Python
J'ai essayé de faire LINE BOT avec Python et Heroku
[Super facile] Faisons un LINE BOT avec Python.
Une histoire sur un amateur faisant une rupture de bloc avec python (kivy) ②
Créez un Twitter BOT avec le SDK GoogleAppEngine pour Python
L'histoire du rubyiste aux prises avec Python :: Dict data with pycall
Une histoire sur un amateur faisant une rupture de bloc avec python (kivy) ①
[Python] Une histoire sur la création d'un bot LINE avec une fonction humaine pratique sans utiliser Salesforce [API de messagerie]
L'histoire de Python et l'histoire de NaN
L'histoire de l'exportation d'un programme
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
Je veux connaître la météo avec LINE bot avec Heroku + Python
Le 14 mars est le jour du rapport de circonférence. L'histoire du calcul du ratio de circonférence avec python
[python, ruby] sélénium-Obtenez le contenu d'une page Web avec le pilote Web
Lire la sortie standard d'un sous-processus ligne par ligne en Python
[LINE Messaging API] Créez un BOT qui se connecte à quelqu'un avec Python
L'idée d'alimenter le fichier de configuration avec un fichier python au lieu de yaml
Créez un programme de jugement de compatibilité avec le module aléatoire de python.
Vérifier l'existence du fichier avec python
Rechercher le labyrinthe avec l'algorithme python A *
L'histoire de la fabrication d'un moule immuable
[Python] [LINE Bot] Créer un robot LINE de retour de perroquet
L'histoire de la manipulation des variables globales Python
[python] [meta] Le type de python est-il un type?
Faisons un bot Twitter avec Python!
Une histoire qui visualise le présent de Qiita avec Qiita API + Elasticsearch + Kibana
L'histoire d'un capteur de stationnement en 10 minutes avec le kit de démarrage GrovePi +
[Explication AtCoder] Contrôlez les problèmes A, B, C d'ABC182 avec Python!
Calculer l'itinéraire le plus court d'un graphe avec la méthode Dyxtra et Python
Les débutants en Python ont décidé de créer un bot LINE avec Flask (commentaire approximatif de Flask)
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Calculez la probabilité d'être une pièce de calmar avec le théorème de Bayes [python]
Hit une méthode d'une instance de classe avec l'API Web Python Bottle
Recevez une liste des résultats du traitement parallèle en Python avec starmap