[PYTHON] So erstellen Sie einen interaktiven LINE BOT 004 (beantworten Sie den Stichtag eines börsennotierten Unternehmens)

Überblick

Letztes Mal habe ich eine Funktion zum Abrufen von Aktienkursinformationen implementiert, aber tatsächlich: "Richtig, ich habe die Aktien-App verwendet, ohne BOT zu fragen. Es ist nur eine Frage der Zeit, bis der Tsukkomi sagt: "Es ist bequemer", und ich verwende wahrscheinlich täglich eine bestimmte Portfolio-Management-App. Daher möchte ich, dass BOT den Aktienkurs genau bestimmt. Es kommt nicht dazu, das Bedürfnis zu haben. Also ging ich zurück zum Ausgangspunkt, fragte mich, welche Art von Funktion ich wollte, und suchte nach einer praktischeren Funktion.

"Ja, es wäre praktisch, wenn wir die (geplanten) Abrechnungstermine auf einmal erfassen könnten."

Wenn Sie viele Aktien besitzen, ist es ziemlich mühsam, den Zeitplan für einzelne Aktien, Halbjahresergebnisse, vierteljährliche Finanzergebnisse usw. täglich zu verfolgen. Es wäre praktisch, wenn es eine Funktion gäbe, die dies zentral erfassen und visualisieren könnte, und vor allem denke ich, es wäre gut, wenn es die ursprüngliche Art von BOT wäre.

Dieses Mal möchte ich eine äußerst fortschrittliche Schabetechnik entwickeln, die darauf abzielt, die Fähigkeiten zum Extrahieren und Analysieren von Informationen von der Website zu stärken.

Systemkonfiguration

Wenn Sie den Aktivierungscode einschließlich des Markencodes über die LINE-App (①) eingeben, greift BOT auf die Website zu, untersucht das Datum der Ankündigung der letzten Finanzergebnisse (geplant) und antwortet (②). Es wird auch davon ausgegangen, dass einzelne Aktien spezifiziert werden oder ein Portfolio im Voraus festgelegt wird und mehrere Aktien gleichzeitig erworben werden.

システム構成004.png

1. Auswahl der Zielwebsite

Wir werden eine Website namens Stock Forecast verwenden. Wenn Sie die Seite für einzelne Aktien öffnen, wird das Datum der letzten Bekanntgabe der Finanzergebnisse (geplant) an der in der folgenden Abbildung gezeigten Position angezeigt. Wenn die Finanzergebnisse bekannt gegeben wurden, wird diese Tatsache zusammen mit dem Datum angezeigt. Wenn die Ankündigung in Zukunft geplant ist, wird sie zusammen mit dem Datum als geplantes Ankündigungsdatum angezeigt. Die dieser Position entsprechende HTML-Quelle ist die Klasse "header_main", beginnend in Zeile 222. Sie können sehen, dass alle gewünschten Informationen darunter enthalten sind.

HTML BODY.png

Daher scheint es, dass diese Mission durch das Verständnis der Fähigkeiten der folgenden drei Prozesse verwirklicht werden kann.

  1. Holen Sie sich die HTML-Quelle
  2. Perspektive, Extrahieren des Tags
  3. String-Formatierung

Also, wenn Sie zuerst die Schlussfolgerung schreiben Für 1. Anfragen 2. Für "Schöne Suppe" 3. Für "re" Sehr intelligente Codierung wird realisiert, indem jede von ihnen verwendet wird.

2. Holen Sie sich HTML-Quelle durch Anfragen

Da die Anforderung bereits bei der Implementierung des Chatbots gepackt wurde, werden Details weggelassen. Das Codierungsbeispiel lautet wie folgt

(Beispiel für die Skriptausführung)Verwendung von Anfragen


(botenv2) [botenv2]$ python
Python 3.6.7 (default, Dec  5 2018, 15:02:16) 
>>> import requests

#HTML-Quelle abrufen
>>> r = requests.get('https://kabuyoho.ifis.co.jp/index.php?action=tp1&sa=report_top&bcode=4689')

#Inhaltsbestätigung
>>> print(r.headers)
{'Cache-Control': 'max-age=1', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html; charset=UTF-8', (Kürzung)
>>> print(r.encoding)
UTF-8
>>> print(r.content)
(Kürzung)

Mit diesem Gefühl ist keine besondere Erklärung erforderlich. Da der gesamte Körperteil in r.inhalt gelagert wird, wird er anschließend gekocht oder gebacken. Sie können das Ziel-HTML-Tag als Schlüssel zum Abrufen von Informationen verwenden.

3. Einführung von Beautiful Soup (Parser)

Es scheint, dass es ein berühmtes Paket ist und bereits verschiedene Parser implementiert. Als ich es einführte, konnte ich diesmal 90% des Zwecks erreichen. ..

Schöne Suppeninstallation


(botenv2) [botenv2]$ pip install BeautifulSoup4

(Beispiel für die Skriptausführung@Fortsetzung)Wie man schöne Suppe benutzt


>>> from bs4 import BeautifulSoup

#Analyse des Körperteils mit Parser
>>> soup = BeautifulSoup(r.content, "html.parser")

Versuchen Sie, die Klasse header_main anzuzeigen.

python


>>> print(soup.find("div", class_="header_main"))

Ausführungsergebnis



<div class="header_main">
<div class="stock_code left">4689</div>
<div class="stock_name left">Z Holdings</div>
<div class="block_update right">
<div class="title left">
Ergebnis bekannt gegeben
                                                        </div>
<div class="settle left">
                                                                        2Q
                                                        </div>
<div class="date left">
                                                                                                   2019/11/01
                                                                                                </div>
<div class="float_end"></div>
</div>
<div class="float_end"></div>
</div>

Es ist wunderbar. Es ist zu bequem, um nicht mehr zu zittern.

3. String-Formatierung

Sie müssen nur noch unnötige Zeichenfolgen löschen. Verwenden Sie die Textmethode, da keine HTML-Tags erforderlich sind.

(Beispiel für die Skriptausführung@Fortsetzung)Textextraktion


>>> s = soup.find("div", class_="header_main").text
>>> print(s)
4689
Z Holdings


Ergebnis bekannt gegeben
                                                 

                                                                        2Q
                                                 

                                                                                                   2019/11/01
                                                                                         




>>> 

Die Tags wurden gelöscht, aber es gibt noch viele mysteriöse Lücken. Ich wusste nicht, ob dies ein Leerzeichen oder ein Meta-Charakter ist, also habe ich mich für einen Moment in ihn verliebt. In einem solchen Fall kann die Substanz angezeigt werden, indem sie im Bytetyp angezeigt wird.

(Referenz)Bestätigung des Zeichencodes


>>> s.encode()
b'\n4689\n\xef\xbc\xba\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xab\xe3\x83\x87\xe3\x82\xa3\xe3\x83\xb3\xe3\x82\xb0\xe3\x82\xb9\n\n\n\t\t\t\t\t\t\t\t\t\xe6\xb1\xba\xe7\xae\x97\xe7\x99\xba\xe8\xa1\xa8\xe6\xb8\x88\n\t\t\t\t\t\t\t\n\n\t\t\t\t\t\t\t\t\t2Q\n\t\t\t\t\t\t\t\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t2019/11/01\n\t\t\t\t\t\t\t\t\t\t\t\t\n\n\n\n'

Der Punkt ist, / n und / t zu entfernen. Ersetzen wir es gnadenlos durch ein Komma und begraben es.

(Beispiel für die Skriptausführung@Fortsetzung)Entfernung von Metazeichen


>>> import re
>>> s = re.sub(r'[\n\t]+', ',', s)
>>> print(s)
,4689,Z Holdings,Ergebnis bekannt gegeben,2Q,2019/11/01,

Wenn Sie die störenden Kommas vor und nach dem Ende entfernen

(Beispiel für die Skriptausführung@Fortsetzung)


>>> s = re.sub(r'(^,)|(,$)','', s)
>>> print(s)
4689,Z Holdings,Ergebnis bekannt gegeben,2Q,2019/11/01

Es fühlt sich gut an. Es scheint, dass es so wie es ist in CSV oder Datenrahmen konvertiert werden kann.

Übrigens, wenn ein nicht existierender Markencode erfasst wird, bleibt der folgende Zeichencode nach der obigen Verarbeitung erhalten.

Für nicht existierenden Bestandscode


>>> print(s)
b'\xc2\xa0'

Dieses \ xc2 \ xa0 bedeutet in Unicode NO-BREAK SPACE und entspricht & nbsp in HTML. Wenn dieser Zeichencode enthalten ist, stört er die nachfolgende Verarbeitung, daher ist es wünschenswert, ihn nach Möglichkeit zu entfernen. (Es scheint ein häufiges Problem beim Scraping von Webseiten zu sein.)

(Referenz) [Python3] Was tun, wenn beim Scraping [\ xa0] auftritt?

&Entfernung von nbsp


s = re.sub(r'[\xc2\xa0]','', s)

4. Implementiert in der BOT App

Hier ist eine funktionalisierte Version des obigen Prozesses.

getSettledata.py


import requests
from bs4 import BeautifulSoup
import re
import logging
logger = logging.getLogger('getSettledata')

source = 'https://kabuyoho.ifis.co.jp/index.php?action=tp1&sa=report_top&bcode='

#Erfassungsfunktion für das Abrechnungsdatum(4689 wenn das Argument leer ist(ZHD)Siehe die Daten von)
def get_settleInfo(code="4689"):

  #Krabbeln
  try:
    logger.debug('read web data cord = ' + code) #logging
    r = requests.get(source + code)
  except:
    logger.debug('read web data ---> Exception Error') #logging
    return None, 'Exception error: access failed'

  #Schaben
  soup = BeautifulSoup(r.content, "html.parser")
  settleInfo = soup.find("div", class_="header_main").text
  settleInfo = re.sub(r'[\n\t]+', ',', settleInfo) #Entfernen von Metazeichen
  settleInfo = re.sub(r'(^,)|(,$)','', settleInfo) #Entfernen Sie Kommas am Anfang und Ende von Zeilen
  settleInfo = re.sub(r'[\xc2\xa0]','', settleInfo) #&nbsp(\xc2\xa0)Umgang mit dem Problem
  logger.debug('settleInfo result = ' + settleInfo) #logging

  if not settleInfo:
    settleInfo = 'Es gibt keine solche Marke ~'

  return settleInfo

if __name__ == '__main__':
  print(get_settleInfo())

Fügen Sie für das Hauptprogramm die bedingte Verzweigungsverarbeitung hinzu, indem Sie den Aktivierungscode wie gewohnt identifizieren. Wenn Sie im Voraus Ihr eigenes Portfolio in "SETTLEVIEW_LIST_CORD" erstellen, sind Sie zur Chargenerfassung berechtigt.

chatbot.py(★ Ergänzung)##Der vorhandene Funktionsteil wird weggelassen, da er nicht geändert wird.


# -*- Coding: utf-8 -*-

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from django.shortcuts import render
from datetime import datetime
from time import sleep
import requests
import json
import base64
import logging
import os
import random
import log.logconfig
from utils import tools
import re
from .getStockdata import get_chart
from .getSettledata import get_settleInfo

logger = logging.getLogger('commonLogging')

LINE_ENDPOINT = 'https://api.line.me/v2/bot/message/reply'
LINE_ACCESS_TOKEN = ''

###
###Ausgelassen
###

SETTLEVIEW_KEY = ['Siedlung','settle'] #★ Ergänzung
SETTLEVIEW_LIST_KEY = ['Liste der Finanzergebnisse'] #★ Ergänzung
SETTLEVIEW_LIST_CORD = ['4689','3938','4755','1435','3244','3048'] #★ Ergänzung

@csrf_exempt
def line_handler(request):

    #exception
    if not request.method == 'POST':
      return HttpResponse(status=200)

    logger.debug('line_handler message incoming') #logging
    out_log = tools.outputLog_line_request(request) #logging
    request_json = json.loads(request.body.decode('utf-8'))

    for event in request_json['events']:
      reply_token = event['replyToken']
      message_type = event['message']['type']
      user_id = event['source']['userId']

      #whitelist
      if not user_id == LINE_ALLOW_USER:
        logger.warning('invalid userID:' + user_id) #logging
        return HttpResponse(status=200)

      #action
      if message_type == 'text':
        if:
        ###
        ###Ausgelassen
        ###

        elif any(s in event['message']['text'] for s in SETTLEVIEW_KEY): #★ Ergänzung
          action_data(reply_token,'settleview',event['message']['text']) #★ Ergänzung

        else:
        ###
        ###Ausgelassen
        ###

    return HttpResponse(status=200)

def action_res(reply_token,command,):
    ###
    ###Ausgelassen
    ###

def action_data(reply_token,command,value):

    #Aktienchart
    ###
    ###Ausgelassen
    ###

    #######################################################★ Ergänzung von hier
    #Finanzinformation
    elif command == 'settleview':
      logger.debug('get_settleInfo on') #logging

      #Kollektiver Erwerb von Portfolioaktien
      if any(s in value for s in SETTLEVIEW_LIST_KEY): 
        logger.debug('get_settleInfo LIST') #logging

        results = []
        for cord in SETTLEVIEW_LIST_CORD:
          results.append(get_settleInfo(cord))

        logger.debug('get_settleInfo LIST ---> ' + '\n'.join(results)) #logging
        response_text(reply_token,'\n'.join(results))

      #Erwerb einzelner Aktien
      else:
        cord = re.search('[0-9]+$', value)
        logger.debug('get_settleInfo cord = ' + cord.group()) #logging

        result = get_settleInfo(cord.group())

        if result[0] is not None:
          response_text(reply_token,result)
        else:
          response_text(reply_token,result[1])
    #######################################################★ Ergänzung bis hierher

def response_image(reply_token,orgUrl,preUrl,text):
    ###
    ###Ausgelassen
    ###

def response_text(reply_token,text):
    payload = {
      "replyToken": reply_token,
      "messages":[
        {
          "type": 'text',
          "text": text
        }
      ]
    }
    line_post(payload)

def line_post(payload):
    url = LINE_ENDPOINT
    header = {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + LINE_ACCESS_TOKEN
    }
    requests.post(url, headers=header, data=json.dumps(payload))
    out_log = tools.outputLog_line_response(payload) #logging
    logger.debug('line_handler message -->reply') #logging

def ulocal_chatting(event):
    ###
    ###Ausgelassen
    ###

Damit ist der Vorgang abgeschlossen.

line_Bot starten


(botenv2) [line_bot]$ gunicorn --bind 127.0.0.1:8000 line_bot.wsgi:application

Wenn Sie eine Nachricht gemäß dem Format aus der LINE-App löschen, wird das Ergebnis zurückgegeben.

sc003.png

Wenn Sie alles auf einmal erhalten möchten, geben Sie "Financial Statement List" ein.

sc004.png

Es dauert ungefähr 1 Sekunde, um 6 Marken seriell zu messen. Ich war beeindruckt von der schnelleren Verarbeitung, als ich es mir vorgestellt hatte, aber falls es mich zu sehr stört, werde ich sie mäßig verwenden, um nicht häufig darauf zuzugreifen. Bis hierher für diese Zeit.

Recommended Posts

So erstellen Sie einen interaktiven LINE BOT 004 (beantworten Sie den Stichtag eines börsennotierten Unternehmens)
Die weltweit am einfachsten zu verstehende Erklärung zur Herstellung von LINE BOT (1) [Kontoerstellung]
Wie man einen lockeren Bot macht
Die weltweit am einfachsten zu verstehende Erklärung, wie LINE BOT erstellt wird (3) [Zusammenarbeit mit dem Server mit Git]
So erstellen Sie einen LINE-Bot mit künstlicher Intelligenz mit der Flask + LINE Messaging-API
So setzen Sie eine Zeilennummer am Anfang einer CSV-Datei
So berechnen Sie die Volatilität einer Marke
So erstellen Sie einen Raspberry Pi, der die Tweets eines bestimmten Benutzers spricht
So erstellen Sie einen Artikel über die Befehlszeile
Erstellen Sie einen BOT, der die Discord-URL verkürzt
So erstellen Sie ein interaktives CLI-Tool mit Golang
Grundlagen von PyTorch (2) - Wie erstelle ich ein neuronales Netzwerk?
Wie man das Dokument der magischen Funktion (Linienmagie) trifft
So zeigen Sie das Änderungsdatum einer Datei in C-Sprache bis zu Nanosekunden an
Erklären, wie LINE BOT auf einfachste Weise der Welt erstellt werden kann (2) [Vorbereiten der Bot-Anwendung in einer lokalen Umgebung mit Django of Python]
So erstellen Sie mit Flask einen BOT für Cisco Webex-Teams
[Python] So erstellen Sie eine Liste von Zeichenfolgen Zeichen für Zeichen
Machen Sie einen LINE BOT (Chat)
[Python] Ich habe versucht, LINE BOT die Wettervorhersage beantworten zu lassen
So ermitteln Sie den Skalierungskoeffizienten eines bipolaren Wavelets
So verbinden Sie den Inhalt der Liste mit einer Zeichenfolge
Ich habe einen Linienbot erstellt, der das Geschlecht und das Alter einer Person anhand des Bildes errät
So bestimmen Sie die Existenz eines Selenelements in Python
Wie Sie die interne Struktur eines Objekts in Python kennen
So machen Sie einen String in Python zu einem Array oder ein Array zu einem String
So überprüfen Sie die Speichergröße einer Variablen in Python
Erstellen Sie das Thema von Pythonista 3 wie Monokai (wie Sie Ihr eigenes Thema erstellen)
So erstellen Sie einen Befehl zum Lesen der Einstellungsdatei mit Pyramide
So überprüfen Sie die Speichergröße eines Wörterbuchs in Python
So ermitteln Sie die Speicheradresse des Pandas-Datenrahmenwerts
So geben Sie das Ausgabeergebnis des Linux-Befehls man in eine Datei aus
So ermitteln Sie die Scheitelpunktkoordinaten eines Features in ArcPy
So extrahieren Sie die gewünschte Zeichenfolge aus einem Befehl in Zeile 4
[Python] Wie erstelle ich eine Matrix aus sich wiederholenden Mustern (repmat / tile)
[NNabla] So entfernen Sie die mittlere Ebene eines vorgefertigten Netzwerks
Wie erstelle ich eine japanisch-englische Übersetzung?
Wie erstelle ich einen Crawler?
So erstellen Sie eine rekursive Funktion
[Blender] So erstellen Sie ein Blender-Plug-In
Wie erstelle ich einen Crawler?
Die Geschichte, wie ein Geschäft BOT (AI LINE BOT) nach Go To EAT in der Präfektur Chiba durchsucht (1)
[Fabric] Ich war süchtig danach, Boolesche Werte als Argument zu verwenden. Notieren Sie sich also die Gegenmaßnahmen.
Die Geschichte, wie man mit Python einen 100-Yen-Frühstücks-Bot für die Universität macht
Python-Anfänger haben beschlossen, einen LINE-Bot mit Flask zu erstellen (Flask-Kommentar)
Wie man einen Janken-Bot macht, der leicht bewegt werden kann (Kommentar)
[Einführung in Python] So sortieren Sie den Inhalt einer Liste effizient mit Listensortierung
[NNabla] Hinzufügen einer Quantisierungsschicht zur mittleren Schicht eines trainierten Modells
So erstellen Sie einen Wrapper, der die Signatur der zu umschließenden Funktion beibehält
So spielen Sie ein Video ab, während Sie die Anzahl der Bilder ansehen (Mac)
Ein Beispiel für die Antwort auf die Referenzfrage der Studiensitzung. Mit Python.
[Python] Wie man eine Klasse iterierbar macht
So überprüfen Sie die Version von Django
Die Geschichte, wie ein Geschäft BOT (AI LINE BOT) nach Go To EAT in der Präfektur Chiba durchsucht (2) [Übersicht]
Teil 1 Ich habe ein Beispiel für die Antwort auf das Referenzproblem geschrieben, wie man in Python in Echtzeit offline schreibt
So speichern Sie die Feature-Point-Informationen des Bildes in einer Datei und verwenden sie zum Abgleichen
So erstellen Sie einen benutzerdefinierten Backtrader-Indikator
Wie erstelle ich eine Pelican Site Map?
Erstellt einen Slack-Bot, der AWS Lambda über das Ablaufdatum eines SSL-Zertifikats bestätigt und benachrichtigt