[PYTHON] Code d'acquisition de stock par grattage (Selenium)

1 Et cet article?

Lors de l'analyse technique, etc., des données sur le cours de l'action pour chaque émission pendant une période déterminée sont nécessaires. Dans le cas des actions américaines, il est facile d'utiliser Pandas Reader pour accéder à l'API dédiée afin d'obtenir des données sur le cours des actions pour une période donnée, mais dans le cas des actions japonaises, il n'y a pas d'API permettant d'obtenir gratuitement les cours des actions. </ b> De plus, il est courant d’acquérir des données sur le cours des actions en effectuant un scraping Web, mais l’acquisition d’actions japonaises et la plupart des sites qui affichent des cours boursiers interdisent le scraping. </ b> Soit dit en passant, Yahoo Finance est interdit de gratter. Pour les actions japonaises, le site appelé Stock Investment Memo convient pour le scraping Web et vous pouvez obtenir des données sur les cours des actions individuelles. Cependant, Stock Investment Memo ne prend pas en charge le type d'indice (Nikkei 225) ou les actions américaines.

Par conséquent, les données de cours des actions japonaises individuelles sont acquises par Stock Investment Memo, et pour les systèmes d'indices tels que Nikkei 225 et les actions américaines, le code à acquérir par pandas_datareader est créé en Python. C'était.

Site de mémo d'investissement en actions </ b> 92.JPG

2 Je publierai le code.

Ce qui suit est le code pour acquérir les prix des actions japonaises individuelles, le système d'indices (Nikkei 225) et les actions américaines. Nous permettons d'acquérir les cours des actions des trois dernières années contre la date record. Les actions japonaises individuelles sont extraites du site de mémo d'investissement en actions. Les systèmes d'indices et les actions américaines utilisent pandas_datareader pour accéder à l'API et acquérir des données sur les cours des actions. Le scraping est plus lent que l'accès à l'API. Par conséquent, lors de l'acquisition des données sur le prix des actions japonaises, si le stock a déjà acquis le prix de l'action, la quantité de raclage est réduite afin que le traitement soit terminé plus tôt.

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 #Chargez la bibliothèque d'acquisition de données boursières américaines


####(1)Numéro de stock à acquérir,Entrez l'année de base d'acquisition.#######

STOCKNUMS=[4800,1570,7752,'^N225','VOOV','^DJI','JPY=X']   #Entrez le numéro de stock que vous souhaitez obtenir.
#STOCKNUMS=[1570]
YEAR=2020 #Entrez l'année de base d'acquisition. Acquérir des données sur les cours des actions des deux dernières années à partir de l'année de base d'acquisition.

####(2)Définissez le pilote Chrome.#######

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

####(3)Pas d'environnement X(Réalisé sur la console)Si tel est le cas, activez la commande d'affichage suivante. Lors de l'exécution avec jupyter, désactivez la commande d'affichage suivante#######

#Comment utiliser Selenium en lançant un affichage virtuel (Xvfb) à l'aide du package pyvirtualdisplay
display = Display(visible=0, size=(1024, 1024))
display.start()


####(4)Définir divers dossiers##############

EXECUTABLE_PATH="xxxxxxxxxxxxxxxxxx" #/chromedriver.Spécifiez le chemin d'accès exe.
HOME_PATH="yyyyyyyyyyyyyyyyyy" #Spécifiez l'emplacement pour enregistrer les données de prix de l'action.


#### (5)Classe d'acquisition d'actions GET_KABUDATA #####

class GET_KABUDATA():

    ### (5-1)Définir un constructeur###
    def __init__(self,stocknum,year):
    
        stocknum=str(stocknum)

                
        try:
            print('Numéro de marque' + str(stock)+'Obtenez des données de stock de')

            #le fichier csv n'existe pas(Les marques vont acquérir des données pour la première fois cette fois)Si
            if os.path.exists(HOME_PATH + str(stocknum)+'.csv')==False:
                #stocknum(nom commercial)N'est pas un type numérique(=S'il ne s'agit pas d'un stock individuel japonais)
                if stocknum.isnumeric()==False:
                    self.get_PandasDR(stocknum) #pandas_Lancer le lecteur

                #stocknum(nom commercial)Si est un type numérique(=Pour les actions japonaises individuelles)
                else:
                    self.get_new_stockdat(stocknum,year) #Grattage des données des 3 dernières années à partir du mémo d'investissement en actions.
            
            #Si le fichier csv existe(Pour les stocks pour lesquels des données ont été acquises dans le passé)           
            else:
                #stocknum(nom commercial)N'est pas un type numérique(=S'il ne s'agit pas d'un stock individuel japonais)
                if str(stocknum).isnumeric()==False:
                    self.get_PandasDR(stocknum) #pandas_Lancer le lecteur
                
                #stocknum(nom commercial)Si est un type numérique(=Pour les actions japonaises individuelles)
                else:
                    self.get_add_stockdat(stocknum,year) #Obtenez les données de cours des actions pour les dates que vous ne possédez pas actuellement à partir du mémo d'investissement en actions et ajoutez-les au fichier csv.

            print('Numéro de marque' + str(stock)+'Acquisition terminée des données de cours')
            print('**********')

        #La gestion des erreurs(Un numéro de stock inexistant a été spécifié. Le site de mémo d'investissement en stock est en panne et les données ne peuvent pas être récupérées) 
        except Exception as e:
            print(e)
            print('Échec d'acquisition de stock')                
                
                
    ### (5-2)Dans le cas d'une action dont le cours de bourse a été acquis dans le passé, la différence entre les données de cours de bourse sur le serveur et les données de cours de bourse acquises est comparée, et seule la différence est acquise et écrite dans le fichier csv.
    def get_add_stockdat(self,stocknum,year):
        

        #(5-2-1)Initialisez diverses variables.
        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)Accédez à la liste des stocks individuels affichés dans la note d'investissement(Grattage)。
        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)Spécifiez chaque ligne du tableau des prix de l'action et lisez le cours de l'action de chaque jour
        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])) #Avoir un rendez-vous
            s_open.append(kabudat[1]) #Obtenez le prix d'ouverture
            s_high.append(kabudat[2]) #Obtenez le prix élevé.
            s_low.append(kabudat[3]) #Obtenez le prix bas.
            s_close.append(kabudat[4]) #Obtenez le cours de clôture.
            s_volume.append(kabudat[5]) #Obtenez le volume.
            s_stock={'DATE':s_date,'CLOSE':s_close,'OPEN':s_open,'HIGH':s_high,'LOW':s_low,'VOL':s_volume} #Prix ouvert,Prix élevé,Bas prix,le dernier prix,Ajouter du volume à la liste


        dfstock=pd.DataFrame(s_stock,columns=["DATE","CLOSE","OPEN","HIGH","LOW","VOL"]) #Listes_Convertissez le stock en DataFrame.
        dfstock.set_index("DATE",inplace=True)
        dfstock=dfstock.sort_index() #Organisez les données de prix des actions acquises dans l'ordre chronologique.
        dfstock.reset_index("DATE",inplace=True)

                
        dfstock_csv= pd.read_csv(HOME_PATH + str(stocknum)+'.csv', index_col=0) #Lisez les données de cours de bourse enregistrées sur le serveur à partir du fichier csv.
        dfstock_csv.reset_index("DATE",inplace=True)  #Annuler la spécification d'index
        

        #(5-2-4)Obtenez la dernière date des données de stock nouvellement récupérées sur le site
        dfstock_latest = dfstock['DATE'].iloc[dfstock['DATE'].count()-1]
        dfstock_latest=datetime.datetime.strptime(dfstock_latest, '%Y/%m/%d') #Réglez la date sur le type de caractère
        dfstock_latest_date=datetime.date(dfstock_latest.year, dfstock_latest.month, dfstock_latest.day) #Changer la date du type de caractère au type de date
        
        
        #(5-2-5)Obtenez la dernière date des données de cours de bourse stockées sur le serveur.
        dfstock_csv_latest = dfstock_csv['DATE'].iloc[dfstock_csv['DATE'].count()-1]
        dfstock_csv_latest=datetime.datetime.strptime(dfstock_csv_latest, '%Y/%m/%d') #Réglez la date sur le type de caractère
        dfstock_csv_latest_date =datetime.date(dfstock_csv_latest.year, dfstock_csv_latest.month, dfstock_csv_latest.day) #Changer la date du type de caractère au type de date
      
        #(5-2-6)Calcule la différence entre la dernière date des données de cours de bourse nouvellement récupérées sur le site et la dernière date des données de cours de bourse stockées sur le serveur.
        difday=dfstock_latest_date - dfstock_csv_latest_date 


       
        #(5-2-7)Ajoutez la pénurie de données de cours de bourse aux données de cours de bourse stockées sur le serveur pour la mettre à jour.
        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} 
            

        #Convertir les données de stock de rupture du format de liste au format DataFrame
        add_dfstock=pd.DataFrame(add_s_stock,columns=["DATE","CLOSE","OPEN","HIGH","LOW","VOL"])    

        #(5-2-8)Ajoutez la pénurie de données de cours de bourse aux données de cours de bourse stockées sur le serveur.
        dfstock=pd.concat([dfstock_csv, add_dfstock])  

        #(5-2-9)Exporter les données de cours de bourse mises à jour au format CSV
        dfstock.set_index("DATE",inplace=True)
        dfstock.to_csv(HOME_PATH + str(stocknum)+'.csv')
        
        
        browser.close()#Fermez le navigateur Si vous n'écrivez pas en dehors de l'instruction for, une erreur se produira
        
 
     ### (5-3)Acquérir de nouvelles données sur le cours des actions.
    def get_new_stockdat(self,stocknum,year):

         #(5-3-1)Initialisez diverses variables.
        s_date=[]
        s_open=[]
        s_high=[]
        s_low=[]
        s_close=[]
        s_volume=[]
        dfstock=[]

        #(5-3-2)Accédez à la liste des stocks individuels affichés dans la note d'investissement(Grattage)。
        browser = webdriver.Chrome(options=options,executable_path=EXECUTABLE_PATH)

        #(5-3-3)Obtenez des données sur le cours des actions des 3 dernières années à partir du mémo d'investissement en actions
        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)Spécifiez chaque ligne du tableau des prix de l'action et lisez le cours de l'action de chaque jour
            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"]) #liste->Changer pour DataFrame
        dfstock.set_index("DATE",inplace=True)
        dfstock=dfstock.sort_index() #Organisez les données de prix des actions acquises dans l'ordre chronologique.
        dfstock.to_csv(HOME_PATH + str(stocknum)+'.csv') #Exportez les données de cours de bourse dans un fichier CSV.

        browser.close()#Fermez le navigateur Si vous n'écrivez pas en dehors de l'instruction for, une erreur se produira

        
 

     ###Acquérir des données sur les prix des actions et des indices américains
    def get_PandasDR(self,stocknum):
        ed=datetime.datetime.now()
        st=datetime.datetime.now()- datetime.timedelta(days=600)        
        df=web.DataReader(stocknum, 'yahoo',st,ed) #Obtenez des données sur l'action Nikkei 225
        df=df.drop(columns='Adj Close') #Supprimer la colonne A.
        df.reset_index("Date",inplace=True)
        df= df.rename(columns={'Date': 'DATE','High': 'HIGH', 'Low': 'LOW',  'Open': 'OPEN', 'Close': 'CLOSE',  'Volume': 'VOL' })#Remplacez chaque nom de colonne par le nom de colonne souhaité.
        df = df[['DATE','CLOSE','HIGH','LOW','OPEN','VOL']]
        df.set_index("DATE",inplace=True)
        df.to_csv(HOME_PATH + str(stocknum)+'.csv') #Ecrire df dans un fichier csv externe
        
        
        
 
#############Programme principal##################

#Acquiert le prix de l'action de l'action spécifiée.
if __name__ == '__main__':        
    
    for stock in STOCKNUMS:
        GET_KABUDATA(stock,YEAR)

    print('L'acquisition des stocks est terminée.')

3 points à noter lors de l'exécution du code

3-1 Définition de la marque à acquérir

Saisissez le numéro de stock du stock à acquérir dans la variable STOCKNUMS </ b>.

python


STOCKNUMS=[4800,1570,7752,'^N225','VOOV','^DJI','JPY=X']   #Entrez le numéro de stock que vous souhaitez obtenir.
#STOCKNUMS=[1570]
YEAR=2020 #Entrez l'année de base d'acquisition. Acquérir des données sur les cours des actions des deux dernières années à partir de l'année de base d'acquisition.

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

3-2 Paramètres de grattage

Si vous souhaitez exécuter le code dans l'environnement où le navigateur ne démarre pas (environnement de console), activez le code suivant. Au contraire, si l'environnement tel que jupyter démarre le navigateur, désactivez ce qui suit.

python


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

3-3 Réglage PATH

Définissez le chemin (EXECUTABLE_PATH) où se trouve le pilote chrome chromedriver.exe et le chemin (HOME_PATH) où les données de cours boursier sont enregistrées.

python


EXECUTABLE_PATH="xxxxxxxxxxxxxxxxxx" #/chromedriver.Spécifiez le chemin d'accès exe.
HOME_PATH="yyyyyyyyyyyyyyyyyy" #Spécifiez l'emplacement pour enregistrer les données de prix de l'action.

Recommended Posts