Récupérer les données souhaitées du site Web en liant Python et Excel

But du grattage

Tout d'abord, il est important de dire ce que vous voulez réaliser en utilisant la technologie même au niveau de la petite application.

J'investis principalement dans des fiducies de placement (ci-après appelées fiducies de placement), mais ces dernières années, les produits des fiducies de placement ont été régulièrement vendus, et je me demande simplement.

"Le produit que j'achète est-il vraiment bon?" "Je pense qu'il existe des produits moins chers et plus rentables."

** Une fois par an ** pense à une telle chose.

C'est pourquoi je recherche sur la page des fiducies d'investissement du site des titres et compare les produits, mais il y a de nombreux éléments que je dois examiner, tels que le prix de base, le ratio élevé, les frais de gestion des frais de fiducie, et même ceux qui restreignent les conditions de recherche dans une certaine mesure sont 5 ~ Je veux comparer environ 10.

** Oh, je veux une liste approximative d'informations sous forme de tableau ...! ** **

C'est le but de ce grattage.

Environnement et site cible

OS:Windows Langage de programmation: Python (3.8) Logiciel: Excel (2016) Éditeur: Visual Studio Code

Un exemple du site cible Chaque page produit de Rakuten Securities (car j'utilise principalement Rakuten Securities) https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000BRT6

La structure de la page est la même pour les autres produits.

J'ai utilisé ** BeautifulSoup ** pour le scraping et ** Openpyxl ** pour créer un lien vers Excel. La raison pour laquelle j'ai choisi ces bibliothèques est que je viens de les rechercher et de nombreux articles utilisent ces bibliothèques. C'est une règle de base pour les débutants d'entrer à partir d'un endroit avec une grande quantité d'informations. (Je n'ai jamais fait Python)

Documentation officielle BeautifulSoup https://www.crummy.com/software/BeautifulSoup/bs4/doc/ Openpyxl https://openpyxl.readthedocs.io/en/stable/tutorial.html

Préparation préalable

J'ai préparé un fichier Excel à l'avance. WS000056.JPG

Éléments de la gauche ・ Nom du fonds · Société de titres ・ Classification (comme s'il s'agit d'un stock national ou d'un stock de pays développé) · Prix de base ・ Actif net (100 millions) ・ Actif net de la dernière fois (100 millions) ・ Augmentation / diminution de l'actif net ・ Dernière distribution ・ Frais d'achat ・ Ratio des frais de gestion (coûts tels que les frais de fiducie et les frais administratifs) ・ URL

C'était fabriqué. La signification des éléments n'est pas liée à cet article, je vais donc l'omettre ici. En bref, pensez-y comme un élément pour comparer les spécifications des fiducies de placement. Il y en a en fait beaucoup plus.

À propos, «le montant de l'actif net précédent (100 millions)» et «l'augmentation / diminution de l'actif net» ont des valeurs numériques et des fonctions définies à l'avance. Je veux prendre la différence entre «l'actif net (100 millions)» et «l'actif net antérieur (100 millions)».

Puisque l '"URL" est également connue à l'avance, je l'écrirai depuis le début.

D'ailleurs, les données à acquérir cette fois sont ** uniquement des informations publiques qui ne nécessitent pas de connexion, etc. **. Je ne reçois pas d'informations sur les produits que j'ai achetés, leur quantité et leur nombre.

Le but est simplement de comparer les produits financiers eux-mêmes.

Grattage

Tout d'abord, préparez-vous à utiliser Beautiful Soup.

fund.py


import requests, bs4

Comme il est supposé que plusieurs URL dans Rakuten Securities seront accédées cette fois, une méthode qui prend les URL comme arguments sera définie à l'avance.

fund.py


#Rakuten Securities
def GetRakutenFund(url):
    res = requests.get(url)
    res.raise_for_status()
    soup = bs4.BeautifulSoup(res.text, "html.parser")

Puisque nous avons déjà décidé les éléments que nous voulons obtenir, nous définirons également la classe.

fund.py


#Classe d'informations sur le fonds
class FundInfo:
    def __init__(self):
        self.name = ''
        self.company = ''
        self.category = ''
        self.baseprice = ''
        self.assets = 0
        self.allotment = 0
        self.commision = ''
        self.cost = 0

** Stockez les informations récupérées par la méthode GetRakutenFund dans l'instance FundInfo **.

Maintenant, obtenez les informations pour obtenir les informations que vous souhaitez sur ce site. https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000BRT6

Bien qu'il soit solide, nous identifierons les éléments en utilisant pleinement les outils de développement. En conséquence, il a été constaté que la structure est la suivante.

nom de l'article nom de la classe
Nom du fonds fund-name
Classification fund-type
Prix de base value-01
Actif net value-02
Distribution la plus récente value-02
Frais d'achat no-fee
Taux de coût de gestion Aucun nom de classe

En gros, si le nom de la classe est unique, vous pouvez facilement obtenir les données, mais cette fois, il semble que ce ne soit pas le cas. L'actif net et les distributions les plus récentes utilisent le même nom de classe et Le taux des frais de gestion n'avait pas de nom de classe.

Donc cette fois, si je ne pouvais pas le spécifier par le nom de la classe, j'ai fait quelque chose comme ** prendre l'élément d'un niveau plus haut et le mettre dans le tableau de contenu **. キャプチャ.PNG

Cette image est regroupée dans une classe appelée tbl-fund-summary. De cela, j'ai extrait l'élément avec le nom de classe value-02.

fund.py


fundsummary = soup.find("table", attrs={"class", "tbl-fund-summary"})
elements = fundsummary.find_all("span", attrs={"class", "value-02"})
fundinfo.assets = elements[0].text
fundinfo.allotment = elements[1].text

Nous avons pu identifier les éléments [0] comme le montant de l'actif net et les éléments [1] comme la dernière distribution.

Spécifiez le ratio des coûts de gestion de la même manière. キャプチャ2.PNG

Cet élément était un élément td unique dans la classe appelée trust-fee de l'élément li.

fund.py


costs = soup.find("li", attrs={"class", "trust-fee"})
elements = costs.find_all("td")
fundinfo.cost = elements[0].text

Enfin, la méthode GetRakutenFund fait ceci:

fund.py


#Rakuten Securities
def GetRakutenFund(url):
    res = requests.get(url)
    res.raise_for_status()
    soup = bs4.BeautifulSoup(res.text, "html.parser")

    fundinfo = FundInfo()
    #Nom du fonds, classification
    fundinfo.name = soup.select_one('.fund-name').text
    fundinfo.company = 'Rakuten'
    fundinfo.category = soup.select_one('.fund-type').text
    #Prix de base, actif net, dernière distribution
    fundsummary = soup.find("table", attrs={"class", "tbl-fund-summary"})
    elemnt = fundsummary.select_one('.value-01')
    fundinfo.baseprice = elemnt.text + elemnt.nextSibling
    elements = fundsummary.find_all("span", attrs={"class", "value-02"})
    fundinfo.assets = elements[0].text
    fundinfo.allotment = elements[1].text
    #Frais de gestion tels que les frais d'achat et les frais de fiducie
    fundinfo.commision = soup.select_one('.no-fee').text
    costs = soup.find("li", attrs={"class", "trust-fee"})
    elements = costs.find_all("td")
    fundinfo.cost = elements[0].text

    return fundinfo

Si vous êtes familier avec le grattage ici, il devrait y avoir une méthode de description plus intelligente.

Et l'appelant de la méthode. Puisqu'il est séparé du fichier de traitement principal, fund.py est importé en tant que fonds.

main.py


nam = fund.GetRakutenFund('https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000BRT6')

Lien vers Excel

J'ai pu obtenir les informations que je souhaitais en tant qu'instance du type FundInfo. Versez ces données dans Excel.

Je veux utiliser Openpyxl, donc veuillez d'abord l'installer à partir de pip, etc. Après l'installation, écrivez une instruction d'importation.

exceloperator.py


import openpyxl

Définissez ensuite une méthode pour effectuer le traitement Excel.

exceloperator.py


def WriteExcel(fund_info_list):

Il y avait des URL ** 4 ** que je n'avais pas écrites auparavant, mais que je voulais obtenir des informations cette fois. Je voudrais donc stocker 4 instances de FundInfo dans une liste (fund_info_list), les transmettre comme arguments à la méthode qui exécute le traitement Excel et effectuer le traitement en boucle.

Tout d'abord, chargez l'Excel préparé à l'avance. Ensuite, récupérez la feuille de calcul que vous souhaitez traiter. Dans ce cas, la feuille «fonds» est la cible.

exceloperator.py


#r ignore la séquence d'échappement
wb = openpyxl.load_workbook(r'Chemin du fichier Excel')
ws = wb['fonds']

Lorsqu'un chemin est spécifié comme argument, les barres obliques inverses, etc. ne sont pas bonnes dans un environnement Windows. Si vous ajoutez r, il ignorera la séquence d'échappement.

Tout ce que vous avez à faire maintenant est de définir chaque élément de FundInfo dans la liste dans la cellule correspondante. Dans mon cas cette fois, les 6ème et 7ème colonnes sont des éléments pour prendre la différence par rapport à la confirmation précédente, donc je ne mettrai pas à jour les données. Il semblait y avoir un moyen de les emballer dans un tableau, mais pour le moment, j'ai pris la méthode de les mettre un par un.

exceloperator.py


row = 2
for fund in fund_info_list:
    col = 1
    #Les 6e et 7e colonnes ne sont pas sujettes à mise à jour
    ws.cell(column=col, row=row, value=fund.name)
    col += 1
    ws.cell(column=col, row=row, value=fund.company)
    col += 1
    ws.cell(column=col, row=row, value=fund.category)
    col += 1
    ws.cell(column=col, row=row, value=fund.baseprice)
    col += 1
    ws.cell(column=col, row=row, value=float(fund.assets.replace(',', '')))
    col += 3
    ws.cell(column=col, row=row, value=int(fund.allotment))
    col += 1
    if fund.commision == 'Aucun':
        ws.cell(column=col, row=row, value=0)
    else:
        ws.cell(column=col, row=row, value=fund.commision)
    col += 1
    ws.cell(column=col, row=row, value=fund.cost)
    row += 1

Une autre chose à noter est que je veux traiter le montant de l'actif net (actifs) et la dernière distribution (attribution) comme des types numériques, donc je les convertis numériquement et les place dans la cellule. Puisqu'il est possible que le montant de l'actif net contienne une virgule séparée par 1000, nous avons ajouté un processus pour supprimer la virgule. Les frais d'achat sont écrits comme "Aucun" sur le site (je l'achète seulement), mais il est plus facile de le traiter comme 0 yen que "Aucun", donc je le convertis ici.

Oh, je veux un incrément ... (murmure de C # er)

Enregistrez-le correctement à la fin. Si vous spécifiez le chemin du fichier ouvert, il sera écrasé et enregistré.

exceloperator.py


wb.save(r'Chemin du fichier Excel')

Le code entier

C'est un débutant qui n'est pas beau, alors jetez un œil.

main.py


import fund, exceloperator

#Fonction principale
#<Aucun frais d'achat / en espèces> Nissei TOPIX Index Fund
nam = fund.GetRakutenFund('https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000BRT6')
#Tawara No Road Stock de pays développés
am_one = fund.GetRakutenFund('https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000CMK4')
#Indice eMAXIS Slim Actions des marchés émergents
emax_emarging = fund.GetRakutenFund('https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000F7H5')
#eMAXIS Slim US Stock (S & P500)
emax_sp500 = fund.GetRakutenFund('https://www.rakuten-sec.co.jp/web/fund/detail/?ID=JP90C000GKC6')

#Écrire à EXCEL
fund_info_list = [nam, am_one, emax_emarging, emax_sp500]
exceloperator.WriteExcel(fund_info_list)

fund.py


#Gratter avec une belle soupe 4
import requests, bs4

#Classe d'informations sur le fonds
class FundInfo:
    def __init__(self):
        self.name = ''
        self.company = ''
        self.category = ''
        self.baseprice = ''
        self.assets = 0
        self.allotment = 0
        self.commision = ''
        self.cost = 0
    
#Rakuten Securities
def GetRakutenFund(url):
    res = requests.get(url)
    res.raise_for_status()
    soup = bs4.BeautifulSoup(res.text, "html.parser")

    fundinfo = FundInfo()
    #Nom du fonds, classification
    fundinfo.name = soup.select_one('.fund-name').text
    fundinfo.company = 'Rakuten'
    fundinfo.category = soup.select_one('.fund-type').text
    #Prix de base, actif net, dernière distribution
    fundsummary = soup.find("table", attrs={"class", "tbl-fund-summary"})
    elemnt = fundsummary.select_one('.value-01')
    fundinfo.baseprice = elemnt.text + elemnt.nextSibling
    elements = fundsummary.find_all("span", attrs={"class", "value-02"})
    fundinfo.assets = elements[0].text
    fundinfo.allotment = elements[1].text
    #Frais de gestion tels que les frais d'achat et les frais de fiducie
    fundinfo.commision = soup.select_one('.no-fee').text
    costs = soup.find("li", attrs={"class", "trust-fee"})
    elements = costs.find_all("td")
    fundinfo.cost = elements[0].text

    return fundinfo

exceloperator.py


#Opération Excel avec openpyxl
import openpyxl

def WriteExcel(fund_info_list):
    #r ignore la séquence d'échappement
    wb = openpyxl.load_workbook(r'Chemin du fichier Excel')
    ws = wb['fonds']
    
    row = 2
    for fund in fund_info_list:
        col = 1
        #Les 6e et 7e colonnes ne sont pas sujettes à mise à jour
        ws.cell(column=col, row=row, value=fund.name)
        col += 1
        ws.cell(column=col, row=row, value=fund.company)
        col += 1
        ws.cell(column=col, row=row, value=fund.category)
        col += 1
        ws.cell(column=col, row=row, value=fund.baseprice)
        col += 1
        ws.cell(column=col, row=row, value=float(fund.assets.replace(',', '')))
        col += 3
        ws.cell(column=col, row=row, value=int(fund.allotment))
        col += 1
        if fund.commision == 'Aucun':
            ws.cell(column=col, row=row, value=0)
        else:
            ws.cell(column=col, row=row, value=fund.commision)
        col += 1
        ws.cell(column=col, row=row, value=fund.cost)
        row += 1

    wb.save(r'Chemin du fichier Excel')

Fichier Excel après le grattage

WS000055.JPG

Impressions

Vous avez peut-être écrit du code Python décent pour la première fois. Je suis content d'avoir pu réaliser le mouvement souhaité. J'ai encore beaucoup de grammaire ...

Tant que mon travail principal est le commerce, il est difficile d'écrire la technologie que j'utilise au travail ... Il n'y a pas beaucoup d'histoires sur le tas que je puisse écrire de façon folle.

Il a déclaré qu'Excel renforcera également sa coopération avec Python. (Vaut-il mieux utiliser xlwings?) En fait, j'aime secrètement Excel, donc si je peux utiliser Excel, je veux continuer à l'utiliser. (le désir)

Recommended Posts

Récupérer les données souhaitées du site Web en liant Python et Excel
[Python] Comment lire les données de CIFAR-10 et CIFAR-100
(Notes diverses) Modèle de mise à jour des données à partir de l'acquisition / traitement des données CSV par Python vers Excel
Exécutez Python à partir d'Excel
Le VIF calculé par Python et le VIF calculé par Excel sont différents .. ??
Collectez des données d'apprentissage automatique en grattant des bases de données publiques biosourcées
Visualisez l'activité des plantes depuis l'espace à l'aide de données satellites et de Python
[Python] Extraction / combinaison de données aléatoires à partir de DataFrame en utilisant random et pandas
Acquisition automatique des données de niveau d'expression génique par python et R
Obtenez des données de VPS MySQL avec Python 3 et SQL Alchemy
Lire la feuille Excel et le processus en boucle ligne par ligne Python VBA
Scraping avec Node, Ruby et Python
Obtenir des données de Quandl en Python
Python, rendement, retour et parfois rendement de
Grattage avec Python, Selenium et Chromedriver
Grattage avec Python et belle soupe
Lire et utiliser des fichiers Python à partir de Python
À propos de Python, à partir et à l'importation, comme
Hashing de données en R et Python
[Python] Informations sur les lentilles de grattage sur price.com
Extraire et tracer les dernières données démographiques à partir des données PDF fournies par la ville
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (4. Structure des données)
[python] Une histoire sur la collecte de noms de compte Twitter à partir de noms de descripteurs (comme @ 123456) en combinant BeautifulSoup et Excel entrée / sortie.
J'ai essayé de récupérer les données de conversation d'ASKfm
Obtenez des informations sur la propriété en grattant avec python
Construction de pipeline de données avec Python et Luigi
Recevoir des données textuelles de mysql avec python
[Note] Obtenir des données de PostgreSQL avec Python
Communication socket et traitement multi-thread par Python
Utiliser le type de données PostgreSQL (jsonb) à partir de Python
Python: lecture de données JSON à partir de l'API Web
Convertir des données Excel en JSON avec python
Structure de données Python et implémentation interne ~ Liste ~
Structure et fonctionnement des données Python (mémo d'apprentissage Python ③)
Portage et modification du solveur de doublets de python2 vers python3.
[Python] Application Web à partir de 0! Pratique (4) - Mise en forme des données-
Scraping de sites Web à l'aide de JavaScript en Python
Représentez facilement des données graphiques dans le shell et Python
Scraping depuis un site authentifié avec python
Communication socket par langage C et Python
Organisez les données séparées par dossier avec Python
Compressez les données python et écrivez sur sqlite
Pratiquer le web scraping avec Python et Selenium
Scraping Web facile avec Python et Ruby
[Note] Exécuter du code Python à partir d'Excel (xlwings)
[python] Lisez le fichier html et entraînez-vous au scraping
En liant Maya avec Excel ou des feuilles de calcul ~
Communication de données chiffrées entre Python et C #
[Python] De l'analyse morphologique des données CSV à la sortie CSV et à l'affichage graphique [GiNZA]
Python --Lisez les données d'un fichier de données numériques et recherchez la ligne de régression multiple.
WEB grattage avec python et essayez de créer un nuage de mots à partir des critiques
Machine Learning avec docker (40) avec anaconda (40) "Hands-On Data Science and Python Machine Learning" Par Frank Kane