[PYTHON] Aktienerfassungscode durch Schaben (Selen)

1 Was ist mit diesem Artikel?

Bei der Durchführung technischer Analysen usw. sind Aktienkursdaten für einen festgelegten Zeitraum jeder Ausgabe erforderlich. Bei US-Aktien ist es einfach, mit Pandas Reader auf die dedizierte API zuzugreifen, um Aktienkursdaten für einen festgelegten Zeitraum abzurufen. Bei japanischen Aktien gibt es jedoch keine API, mit der Aktienkurse kostenlos abgerufen werden können. </ b> Es ist auch Standard, Aktienkursdaten durch Web-Scraping zu erfassen, aber die Erfassung japanischer Aktien und der meisten Websites, auf denen Aktienkurse veröffentlicht werden, verbietet das Scraping. </ b> Yahoo Finance ist es übrigens untersagt, zu kratzen. Für japanische Aktien ist die Website Stock Investment Memo für das Web-Scraping in Ordnung, und Sie können Aktienkursdaten für einzelne Aktien abrufen. Stock Investment Memo unterstützt jedoch weder den Indextyp (Nikkei 225) noch US-Aktien.

Daher werden die Aktienkursdaten einzelner japanischer Aktien von Stock Investment Memo erfasst, und für Indexsysteme wie Nikkei 225 und US-Aktien wird der von pandas_datareader zu erfassende Code in Python erstellt. Es war.

Stock Investment Memo Site </ b> 92.JPG

2 Ich werde den Code posten.

Das Folgende ist der Code zum Erfassen der Aktienkurse einzelner japanischer Aktien, des Indexsystems (Nikkei 225) und US-amerikanischer Aktien. Wir ermöglichen es, Aktienkurse der letzten drei Jahre zum Stichtag zu erwerben. Einzelne japanische Aktien werden von der Website für Aktieninvestitionsnotizen abgekratzt. Indexsysteme und US-Aktien verwenden pandas_datareader, um auf die API zuzugreifen und Aktienkursdaten zu erfassen. Das Scraping ist langsamer als der Zugriff auf die API. Wenn daher die Aktienkursdaten japanischer Aktien erfasst werden und die Aktie bereits den Aktienkurs erfasst hat, wird der Kratzaufwand reduziert, sodass die Verarbeitung früher abgeschlossen wird.

test.py


#-*- coding:utf-8 -*-
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
import time
import pandas as pd
import datetime
from pyvirtualdisplay import Display
from selenium.webdriver.common.by import By
import os.path
import pandas_datareader.data as web #Laden Sie die Erfassungsbibliothek mit US-Bestandsdaten


####(1)Bestellnummer zu erwerben,Geben Sie das Basisjahr der Akquisition ein.#######

STOCKNUMS=[4800,1570,7752,'^N225','VOOV','^DJI','JPY=X']   #Geben Sie die Bestandsnummer ein, die Sie erhalten möchten.
#STOCKNUMS=[1570]
YEAR=2020 #Geben Sie das Basisjahr der Akquisition ein. Erfassen Sie Aktienkursdaten für die letzten zwei Jahre ab dem Basisjahr der Akquisition.

####(2)Stellen Sie den Chrome-Treiber ein.#######

options = Options() 
options.add_argument('--headless')
options.add_argument('--disable-gpu')

####(3)Keine X-Umgebung(Auf der Konsole durchgeführt)Wenn ja, aktivieren Sie den folgenden Anzeigebefehl. Deaktivieren Sie bei Ausführung mit jupyter den folgenden Anzeigebefehl#######

#Verwendung von Selen durch Starten einer virtuellen Anzeige (Xvfb) mit dem Paket pyvirtualdisplay
display = Display(visible=0, size=(1024, 1024))
display.start()


####(4)Legen Sie verschiedene Ordner fest##############

EXECUTABLE_PATH="xxxxxxxxxxxxxxxxxx" #/chromedriver.Geben Sie den exe-Pfad an.
HOME_PATH="yyyyyyyyyyyyyyyyyy" #Geben Sie den Speicherort für die Aktienkursdaten an.


#### (5)Aktienerwerbsklasse GET_KABUDATA #####

class GET_KABUDATA():

    ### (5-1)Definieren Sie einen Konstruktor###
    def __init__(self,stocknum,year):
    
        stocknum=str(stocknum)

                
        try:
            print('Markennummer' + str(stock)+'Bestandsdaten abrufen von')

            #CSV-Datei existiert nicht(Marken, die diesmal zum ersten Mal Daten erfassen)Wenn
            if os.path.exists(HOME_PATH + str(stocknum)+'.csv')==False:
                #stocknum(Handelsname)Ist kein numerischer Typ(=Wenn es sich nicht um eine japanische Einzelaktie handelt)
                if stocknum.isnumeric()==False:
                    self.get_PandasDR(stocknum) #pandas_Führen Sie den Reader aus

                #stocknum(Handelsname)If ist ein numerischer Typ(=Für einzelne japanische Aktien)
                else:
                    self.get_new_stockdat(stocknum,year) #Scraping der Daten für die letzten 3 Jahre aus der Aktieninvestitionsnotiz.
            
            #Wenn die CSV-Datei vorhanden ist(Für Bestände, für die in der Vergangenheit Daten erfasst wurden)           
            else:
                #stocknum(Handelsname)Ist kein numerischer Typ(=Wenn es sich nicht um eine japanische Einzelaktie handelt)
                if str(stocknum).isnumeric()==False:
                    self.get_PandasDR(stocknum) #pandas_Führen Sie den Reader aus
                
                #stocknum(Handelsname)If ist ein numerischer Typ(=Für einzelne japanische Aktien)
                else:
                    self.get_add_stockdat(stocknum,year) #Erhalten Sie Aktienkursdaten für Daten, die Sie derzeit nicht besitzen, aus dem Aktieninvestitionsprotokoll und fügen Sie sie der CSV-Datei hinzu.

            print('Markennummer' + str(stock)+'Abgeschlossene Erfassung der Aktienkursdaten')
            print('**********')

        #Fehlerbehandlung(Sie haben eine nicht vorhandene Bestandsnummer angegeben. Die Website für Aktieninvestitionsnotizen ist nicht verfügbar und Daten können nicht erfasst werden) 
        except Exception as e:
            print(e)
            print('Fehlschlag bei der Aktienakquisition')                
                
                
    ### (5-2)Bei einer Aktie, deren Aktienkurs in der Vergangenheit erworben wurde, wird die Differenz zwischen den Aktienkursdaten auf dem Server und den erfassten Aktienkursdaten verglichen, und nur die Differenz wird erfasst und in die CSV-Datei geschrieben.
    def get_add_stockdat(self,stocknum,year):
        

        #(5-2-1)Initialisieren Sie verschiedene Variablen.
        s_date=[]
        s_open=[]
        s_high=[]
        s_low=[]
        s_close=[]
        s_volume=[]
        dfstock=[]
        add_s_date=[]
        add_s_open=[]
        add_s_high=[]
        add_s_low=[]
        add_s_close=[]
        add_s_volume=[]  
        add_s_stock=[] 
        add_dfstock=[]       
        
        #(5-2-2)Greifen Sie auf die Aktienliste der einzelnen Aktien zu, die in der Aktieninvestitionsnotiz angezeigt wird(Schaben)。
        browser = webdriver.Chrome(options=options,executable_path=EXECUTABLE_PATH)
        url='https://kabuoji3.com/stock/'+ str(stocknum) + '/'+ str(year) + '/'
        browser.get(url)
        elem_tmp0 = browser.find_element_by_class_name('data_contents')
        elem_tmp1 = elem_tmp0.find_element_by_class_name('data_block')
        elem_tmp2 = elem_tmp1.find_element_by_class_name('data_block_in')
        elem_tmp3 = elem_tmp2.find_element_by_class_name('table_wrap')
        elem_table= elem_tmp3.find_element_by_class_name('stock_table.stock_data_table')
        elem_table_kabuka=elem_table.find_elements(By.TAG_NAME, "tbody")

        #(5-2-3)Geben Sie jede Zeile der Aktienkurstabelle an und lesen Sie den Aktienkurs jedes Tages
        for i in range(0,len(elem_table_kabuka)):
    
            kabudat=elem_table_kabuka[i].text.split()   
            s_date.append(str(kabudat[0].split('-')[0]) +'/'+ str(kabudat[0].split('-')[1]) +'/'+ str(kabudat[0].split('-')[2])) #Verabredung bekommen
            s_open.append(kabudat[1]) #Holen Sie sich den Eröffnungspreis
            s_high.append(kabudat[2]) #Holen Sie sich den hohen Preis.
            s_low.append(kabudat[3]) #Holen Sie sich den niedrigen Preis.
            s_close.append(kabudat[4]) #Holen Sie sich den Schlusskurs.
            s_volume.append(kabudat[5]) #Holen Sie sich die Lautstärke.
            s_stock={'DATE':s_date,'CLOSE':s_close,'OPEN':s_open,'HIGH':s_high,'LOW':s_low,'VOL':s_volume} #Offener Preis,Hoher Preis,Niedriger Preis,Schlusskurs,Volumen zur Liste hinzufügen


        dfstock=pd.DataFrame(s_stock,columns=["DATE","CLOSE","OPEN","HIGH","LOW","VOL"]) #Liste s_Konvertieren Sie den Bestand in DataFrame.
        dfstock.set_index("DATE",inplace=True)
        dfstock=dfstock.sort_index() #Ordnen Sie die erfassten Aktienkursdaten in chronologischer Reihenfolge an.
        dfstock.reset_index("DATE",inplace=True)

                
        dfstock_csv= pd.read_csv(HOME_PATH + str(stocknum)+'.csv', index_col=0) #Lesen Sie die auf dem Server gespeicherten Aktienkursdaten aus der CSV-Datei.
        dfstock_csv.reset_index("DATE",inplace=True)  #Indexspezifikation abbrechen
        

        #(5-2-4)Holen Sie sich das neueste Datum der neu abgekratzten Bestandsdaten von der Website
        dfstock_latest = dfstock['DATE'].iloc[dfstock['DATE'].count()-1]
        dfstock_latest=datetime.datetime.strptime(dfstock_latest, '%Y/%m/%d') #Stellen Sie das Datum auf Zeichentyp ein
        dfstock_latest_date=datetime.date(dfstock_latest.year, dfstock_latest.month, dfstock_latest.day) #Ändern Sie das Datum vom Zeichentyp in den Datumstyp
        
        
        #(5-2-5)Holen Sie sich das neueste Datum der auf dem Server gespeicherten Aktienkursdaten.
        dfstock_csv_latest = dfstock_csv['DATE'].iloc[dfstock_csv['DATE'].count()-1]
        dfstock_csv_latest=datetime.datetime.strptime(dfstock_csv_latest, '%Y/%m/%d') #Stellen Sie das Datum auf Zeichentyp ein
        dfstock_csv_latest_date =datetime.date(dfstock_csv_latest.year, dfstock_csv_latest.month, dfstock_csv_latest.day) #Ändern Sie das Datum vom Zeichentyp in den Datumstyp
      
        #(5-2-6)Berechnet die Differenz zwischen dem letzten Datum der neu abgekratzten Aktienkursdaten von der Site und dem letzten Datum der auf dem Server gespeicherten Aktienkursdaten.
        difday=dfstock_latest_date - dfstock_csv_latest_date 


       
        #(5-2-7)Fügen Sie den Mangel an Aktienkursdaten zu den auf dem Server gespeicherten Aktienkursdaten hinzu, um sie zu aktualisieren.
        for i in range(len(elem_table_kabuka)-difday.days,len(elem_table_kabuka)):
            

            kabudat=elem_table_kabuka[i].text.split()   
            add_s_date.append(str(kabudat[0].split('-')[0]) +'/'+ str(kabudat[0].split('-')[1]) +'/'+ str(kabudat[0].split('-')[2]))     
            add_s_open.append(kabudat[1])
            add_s_high.append(kabudat[2])
            add_s_low.append(kabudat[3])
            add_s_close.append(kabudat[4])
            add_s_volume.append(kabudat[5])
            add_s_stock={'DATE':add_s_date,'CLOSE':add_s_close,'OPEN':add_s_open,'HIGH':add_s_high,'LOW':add_s_low,'VOL':add_s_volume} 
            

        #Konvertieren Sie Mangelbestandsdaten vom Listenformat in das DataFrame-Format
        add_dfstock=pd.DataFrame(add_s_stock,columns=["DATE","CLOSE","OPEN","HIGH","LOW","VOL"])    

        #(5-2-8)Fügen Sie den Mangel an Aktienkursdaten zu den auf dem Server gespeicherten Aktienkursdaten hinzu.
        dfstock=pd.concat([dfstock_csv, add_dfstock])  

        #(5-2-9)Exportieren Sie die aktualisierten Aktienkursdaten nach CSV
        dfstock.set_index("DATE",inplace=True)
        dfstock.to_csv(HOME_PATH + str(stocknum)+'.csv')
        
        
        browser.close()#Wenn Sie nicht außerhalb der for-Anweisung schreiben, die den Browser schließt, tritt ein Fehler auf.
        
 
     ### (5-3)Erfassen Sie neue Aktienkursdaten.
    def get_new_stockdat(self,stocknum,year):

         #(5-3-1)Initialisieren Sie verschiedene Variablen.
        s_date=[]
        s_open=[]
        s_high=[]
        s_low=[]
        s_close=[]
        s_volume=[]
        dfstock=[]

        #(5-3-2)Greifen Sie auf die Aktienliste der einzelnen Aktien zu, die in der Aktieninvestitionsnotiz angezeigt wird(Schaben)。
        browser = webdriver.Chrome(options=options,executable_path=EXECUTABLE_PATH)

        #(5-3-3)Erhalten Sie Aktienkursdaten für die letzten 3 Jahre aus dem Aktieninvestitionsprotokoll
        for j in range(0,3):
            url='https://kabuoji3.com/stock/'+ str(stocknum) + '/'+ str(year-j) + '/'
            browser.get(url)
            elem_tmp0 = browser.find_element_by_class_name('data_contents')
            elem_tmp1 = elem_tmp0.find_element_by_class_name('data_block')
            elem_tmp2 = elem_tmp1.find_element_by_class_name('data_block_in')
            elem_tmp3 = elem_tmp2.find_element_by_class_name('table_wrap')
            elem_table= elem_tmp3.find_element_by_class_name('stock_table.stock_data_table')
            elem_table_kabuka=elem_table.find_elements(By.TAG_NAME, "tbody")

             #(5-2-4)Geben Sie jede Zeile der Aktienkurstabelle an und lesen Sie den Aktienkurs jedes Tages
            for i in range(0,len(elem_table_kabuka)):
    
                kabudat=elem_table_kabuka[i].text.split()   
                s_date.append(str(kabudat[0].split('-')[0]) +'/'+ str(kabudat[0].split('-')[1]) +'/'+ str(kabudat[0].split('-')[2]))     
                s_open.append(kabudat[1])
                s_high.append(kabudat[2])
                s_low.append(kabudat[3])
                s_close.append(kabudat[4])
                s_volume.append(kabudat[5])
                s_stock={'DATE':s_date,'CLOSE':s_close,'OPEN':s_open,'HIGH':s_high,'LOW':s_low,'VOL':s_volume}

                
        dfstock=pd.DataFrame(s_stock,columns=["DATE","CLOSE","OPEN","HIGH","LOW","VOL"]) #aufführen->Wechseln Sie zu DataFrame
        dfstock.set_index("DATE",inplace=True)
        dfstock=dfstock.sort_index() #Ordnen Sie die erfassten Aktienkursdaten in chronologischer Reihenfolge an.
        dfstock.to_csv(HOME_PATH + str(stocknum)+'.csv') #Exportieren Sie Aktienkursdaten in eine CSV-Datei.

        browser.close()#Wenn Sie nicht außerhalb der for-Anweisung schreiben, die den Browser schließt, tritt ein Fehler auf.

        
 

     ###Erfassen Sie Aktienkursdaten von US-Aktien und -Indizes.
    def get_PandasDR(self,stocknum):
        ed=datetime.datetime.now()
        st=datetime.datetime.now()- datetime.timedelta(days=600)        
        df=web.DataReader(stocknum, 'yahoo',st,ed) #Holen Sie sich Nikkei 225 Lagerdaten
        df=df.drop(columns='Adj Close') #Spalte A löschen.
        df.reset_index("Date",inplace=True)
        df= df.rename(columns={'Date': 'DATE','High': 'HIGH', 'Low': 'LOW',  'Open': 'OPEN', 'Close': 'CLOSE',  'Volume': 'VOL' })#Ändern Sie jeden Spaltennamen in den gewünschten Spaltennamen.
        df = df[['DATE','CLOSE','HIGH','LOW','OPEN','VOL']]
        df.set_index("DATE",inplace=True)
        df.to_csv(HOME_PATH + str(stocknum)+'.csv') #Schreiben Sie df in eine externe CSV-Datei
        
        
        
 
#############Hauptprogramm##################

#Erfasst den Aktienkurs der angegebenen Aktie.
if __name__ == '__main__':        
    
    for stock in STOCKNUMS:
        GET_KABUDATA(stock,YEAR)

    print('Der Aktienerwerb wurde abgeschlossen.')

3 Punkte, die beim Ausführen von Code zu beachten sind

3-1 Einstellung der zu erwerbenden Marke

Geben Sie die Bestandsnummer des zu erwerbenden Bestands in die Variable STOCKNUMS </ b> ein.

python


STOCKNUMS=[4800,1570,7752,'^N225','VOOV','^DJI','JPY=X']   #Geben Sie die Bestandsnummer ein, die Sie erhalten möchten.
#STOCKNUMS=[1570]
YEAR=2020 #Geben Sie das Basisjahr der Akquisition ein. Erfassen Sie Aktienkursdaten für die letzten zwei Jahre ab dem Basisjahr der Akquisition.

^ N225: Nikkei Average, VOOV: Vanguard S & P 500 Value ETF, ^ DJI: NY Dow, JPY = X: Yen USD

3-2 Scraping-Einstellungen

Wenn Sie den Code in einer Umgebung ausführen möchten, in der der Browser nicht gestartet wird (Konsolenumgebung), aktivieren Sie den folgenden Code. Im Gegenteil, wenn die Umgebung wie jupyter den Browser startet, deaktivieren Sie Folgendes.

python


display = Display(visible=0, size=(1024, 1024))
display.start()

3-3 PATH-Einstellung

Legen Sie den Pfad (EXECUTABLE_PATH) fest, in dem sich der Chrome-Treiber chromedriver.exe befindet, und den Pfad (HOME_PATH), in dem die Aktienkursdaten gespeichert werden.

python


EXECUTABLE_PATH="xxxxxxxxxxxxxxxxxx" #/chromedriver.Geben Sie den exe-Pfad an.
HOME_PATH="yyyyyyyyyyyyyyyyyy" #Geben Sie den Speicherort für die Aktienkursdaten an.