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.
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
J'ai préparé un fichier Excel à l'avance.
É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.
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 **.
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.
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')
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')
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')
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