[Python] Pratique Belle Soupe ~ Grattage du tableau des cotes triple simple sur le site officiel de la course de bateaux ~

Objectif

La collecte de données est gênante, n'est-ce pas? Je voulais analyser les courses de bateaux à l'avenir, donc comme pratique pour collecter des données tableau des cotes sur le site officiel des courses de bateaux = 02 & hd = 20200511) est gratté.

Aperçu

Ce que vous voulez gratter et comment sortir

ファイル名 ↑ C'est une triple table! Si vous aimez le jeu, vous devriez l'avoir vu! À partir de cette figure, je veux obtenir la valeur, en faire un type de dictionnaire python et l'appeler comme suit!
print('sample1:', three_rentan_odds_dict['1']['2']['3'])
print('sample2:', three_rentan_odds_dict['6']['5']['4'])

# output:
# sample1: 47.2
# sample2: 285.7

Bien sûr, le type de liste est correct, mais le type de dictionnaire est plus rapide d'accès, et l'ordre dans le tableau n'a pas d'importance, alors ne creusez pas trop ici!

Préparation préalable

Le développement utilise python3.7, mais je pense que vous pouvez utiliser n'importe quelle série 3! Il pourrait être plus facile de copier et coller en utilisant jupyter ou quelque chose comme ça!

Package à installer

Entrez avec pip

#Pour pip
pip install request, beautifulsoup4, numpy

#Pour pipenv
pipenv install request beautifulsoup4 numpy

Ce que tu ne devrais pas faire du tout

Actes qui mettent une charge sur l'autre serveur

Non intentionnellement ou non ** Ne mettez jamais de charge sur l'autre serveur **. Il y a aussi des cas d'arrestation. Plus précisément, il est possible de copier et coller le code source introduit ici tel quel et de ne l'exécuter qu'une seule fois, mais si vous essayez de récupérer les informations de la planification entière à l'aide de l'instruction ** for, la charge sur le serveur sera augmentée. Veuillez ne pas le faire car cela pourrait causer des inconvénients **. Il semble que se gratter à des fins d'analyse de données n'est pas illégal. Pour plus d'informations ici

la mise en oeuvre

Importer du HTML en spécifiant une URL

from urllib.request import urlopen
from bs4 import BeautifulSoup
#En utilisant le tableau des cotes triple simple de la 12e course de l'hippodrome de Toda le 11 mai 2020 à titre d'exemple
target_url = \
    'https://www.boatrace.jp/owpc/pc/race/odds3t?rno=12&jcd=02&hd=20200511'
#Lire html
html_content = urlopen(target_url).read()
print(type(html_content))

# output
# <class 'bytes'>

Charger avec beautifulsoup pour gratter

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_content, 'html.parser')
print(type(soup))

# output
# <class 'bs4.BeautifulSoup'>

Utilisez la méthode select fournie par beautifulsoup.

Dans la méthode select, vous pouvez utiliser le sélecteur css spécifié pour spécifier l'emplacement de la balise html pour le scraping. Cette fois, je voudrais retirer la partie du tableau des cotes du triplé. Par conséquent, utilisez l'outil de vérification du navigateur pour acquérir le sélecteur css de l'emplacement cible. En particulier

  1. Déplacez le curseur sur le tableau et cliquez avec le bouton droit pour ouvrir ** Vérification ** (je pense que F12 convient, mais j'utilise la souris car tilix démarre avec F12) ファイル名
  2. Lorsque vous amenez la souris sur le html de l'outil de vérification, la partie appropriée de la description html sera tricotée sur la page, alors trouvez l'endroit où la partie du tableau est sélectionnée. file name
  3. Cliquez avec le bouton droit à ce moment et sélectionnez Copie-> Sélecteur de copie file name
  4. Préparez la variable target_table_selector et collez-la.
#Collez le sélecteur CSS copié
target_table_selector = \
    'body > main > div > div > div > '\
    'div.contentsFrame1_inner > div:nth-child(6) > table'

# select_Récupérez le html spécifié par la méthode one
odds_table = soup.select_one(target_table_selector)
print(type(odds_table))

# output:
# <class 'bs4.element.Tag'>
# print(odds_table)Lorsque vous exécutez, le code HTML de la partie de table spécifiée uniquement s'affiche

Extraire des éléments de la table des cotes

En regardant l'outil de vérification du navigateur que nous avons vu plus tôt, pour extraire les éléments, seule la partie 'tbody' est requise dans ʻodds_table, alors spécifiez-la avec select_one. Ensuite, afin de stocker chaque ligne sous forme de liste, utilisez select pour spécifier la partie'tr'` et en faire une liste.

#spécification de tbody
odds_table_elements = odds_table.select_one('tbody')

#Spécifiez tr et stockez sous forme de liste
row_list = odds_table_elements.select('tr')
print(len(row_list))

# output:
# 20 :Correspond au nombre de lignes du tableau

Ensuite, en faisant attention à la balise qui stocke la valeur des cotes qui sont les éléments, nous pouvons voir qu'il s'agit d'une classe appelée ʻoddsPoint` dans la balise td. ファイル名 Puisque nous voulons extraire ceci pour chaque ligne, créez d'abord une fonction.

#Traitement à effectuer pour chaque ligne
def getoddsPoint2floatlist(odds_tr):
    #Récupère la liste html de la partie où la valeur de cote est stockée
    html_list = odds_tr.select('td.oddsPoint')
    print(html_list[0])
    # example output:
    # <td class="oddsPoint">47.2</td>
    #En utilisant du texte, vous ne pouvez extraire que les éléments entourés de balises
    text_list = list(map(lambda x: x.text, html_list))
    # print(text_list)
    # example output:
    # ['47.2', '60.3', '588.7', '52.8', '66.0', '248.7']
    #Puisque la cote est une valeur décimale, transtypez-la en type float
    float_list = list(map(
        lambda x: float(x), text_list))
    return float_list

Utilisez la fonction map pour générer une matrice qui extrait uniquement les éléments de la table entière

odds_matrix = list(map(
    lambda x: getoddsPoint2floatlist(x),
    row_list
))

print(odds_matrix)

# output
# [[47.2, 60.3, 588.7, 52.8, 66.0, 248.7],
#  [14.7, 13.3, 994.9, 361.6, 363.8, 1276.0],
#  [12.0, 11.1, 747.7, 67.1, 137.8, 503.6],
#  [26.7, 26.6, 1155.0, 96.5, 123.7, 414.5],
#  [157.0, 188.8, 566.8, 50.4, 64.3, 241.5],
#  [242.2, 215.7, 660.5, 261.5, 314.5, 1037.0],
#  [237.5, 190.8, 561.6, 36.4, 66.8, 183.4],
#  [403.5, 281.1, 926.8, 49.2, 73.1, 183.6],
#  [35.0, 25.4, 1276.0, 750.0, 930.3, 2462.0],
#  [219.2, 152.2, 959.6, 517.5, 799.1, 1950.0],
#  [59.6, 23.6, 963.4, 650.0, 1139.0, 1779.0],
#  [89.4, 38.4, 1433.0, 639.7, 1237.0, 2321.0],
#  [34.6, 23.8, 1019.0, 63.9, 119.7, 387.5],
#  [212.5, 143.8, 752.3, 36.9, 64.1, 174.3],
#  [76.3, 30.5, 1231.0, 270.8, 452.2, 952.1],
#  [79.6, 35.8, 1614.0, 44.9, 84.1, 244.4],
#  [83.7, 90.6, 2031.0, 110.1, 171.1, 391.8],
#  [356.3, 308.5, 1552.0, 63.2, 103.9, 201.7],
#  [159.7, 77.7, 1408.0, 326.7, 560.3, 1346.0],
#  [136.0, 69.0, 1562.0, 71.4, 148.1, 285.7]]

** Ceci termine le grattage! !! ** **

Bonus: stocker dans le type de dictionnaire

Ce n'est pas une partie essentielle du grattage, je vais donc omettre des explications détaillées.

import numpy as np
#tableau numpy
odds_matrix = np.array(odds_matrix)
#Prenez l'inversion, connectez-vous et listez
odds_list = list(odds_matrix.T.reshape(-1))

#Stocker dans un dictionnaire
three_rentan_odds_dict = {}
for fst in range(1, 7):
    if fst not in three_rentan_odds_dict.keys():
        three_rentan_odds_dict[str(fst)] = {}
    for snd in range(1, 7):
        if snd != fst:
            if snd not in three_rentan_odds_dict[str(fst)].keys():
                three_rentan_odds_dict[str(fst)][str(snd)] = {}
            for trd in range(1, 7):
                if trd != fst and trd != snd:
                    three_rentan_odds_dict[str(fst)][str(snd)][str(trd)] = \
                        odds_list.pop(0)

print('sample1:', three_rentan_odds_dict['1']['2']['3'])
print('sample2:', three_rentan_odds_dict['6']['5']['4'])

# output:
# sample1: 47.2
# sample2: 285.7

Achevée

Recommended Posts

[Python] Pratique Belle Soupe ~ Grattage du tableau des cotes triple simple sur le site officiel de la course de bateaux ~
[Python3] Comprendre les bases de Beautiful Soup
[Python] Gratter une table avec Beautiful Soup
Gratter les images des membres du site officiel du groupe Sakamichi
Grattage de table avec belle soupe
[Python] Un mémorandum de belle soupe4
Grattage avec Python et belle soupe
Grattage de site Web avec Beautiful Soup en Python
[Python] Obtenez la dernière date de mise à jour du site Web
Au moment de la mise à jour de python avec ubuntu