** * Cet article est une suite de l'article précédent "Agréger automatiquement la distribution de deck JCG avec Python". ** ** Veuillez également vous référer à la partie qui réutilise la méthode d'analyse et le code utilisés dans l'article précédent.
En outre, cet article suppose les connaissances suivantes.
・ Grammaire de base de Python ・ Grattage Web ・ Création d'une table avec des pandas ・ Visualisation des données par matplotlib
Puisque la première moitié se concentre sur les grandes lignes de l'analyse, je pense que vous pouvez obtenir une certaine image sans connaissance de Python. La seconde moitié se concentrera sur le codage réel en Python.
Cet article contient du code de programmation, donc ** nous vous recommandons de l'afficher dans un navigateur PC **.
Nous regrouperons les decks qui ont atteint le tournoi final JCG et effectuerons une ** analyse comparative du nombre de cartes utilisées.
Dans Article précédent, nous avons analysé la distribution de deck de JCG, mais dans cet article, nous analyserons la liste de deck en détail, donc le tableau ci-dessous Est automatiquement créé.
** Exemple: JCG Shadowverse vendredi 28 août, tournoi final du tournoi de rotation **
Contenu précédent: Analyse de la distribution des archétypes
** Contenu de cette fois **: Analyse comparative des fiches de recrutement
Exemple: Spell W
Suivez les étapes ci-dessous pour procéder à l'analyse.
Il existe de nombreux chevauchements avec le contenu précédent concernant les étapes 1 et 2, veuillez donc vous référer à ici pour une explication plus détaillée.
Comme dans l'article précédent (https://qiita.com/somey/items/7e76a1cf6456619345e0), ** Récupérez le fichier JSON sur le site JCG **. Un exemple du fichier JSON acquis est présenté ci-dessous.
example.json
{
"result": "success",
"participants": [
{
"id": "42155",
"chk": 1, #Statut d'enregistrement
"nm": "somey", #Nom enregistré
"dk": [ #Informations sur le pont
{
"cl": 3, #Classe 1
"hs": "3.3.6so2A.6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6_djc.6_djc.6_djc.5-gka.5-gka.5-gka.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.gPWp2.gPWp2.gPWp2.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6xpaI.5-glM.5-glM.5-glM.6t_RI.6t_RI.6t_RI"
}, #Liste des cartes Deck 1 (pour être exact, une partie de l'URL du portail)
{
"cl": 8, #Classe 2
"hs": "3.8.71TeA.71TeA.71TeA.6zemS.6zemS.6zemS.71QTC.71QTC.71QTC.6zd2w.6zd2w.6zd2w.6s2wi.6zcK2.6zcK2.6zcK2.6s65g.6zcKC.6zcKC.6zcKC.6s5My.6s5My.6s5My.6zhCY.6zhxQ.6zhxQ.6zhxQ.6-UTo.6-UTo.71Xo6.71Xo6.71Xo6.6oEnY.6oEnY.6oEnY.6oHDo.6oHDo.6vvW6.6vvW6.6vvW6"
} #Liste des cartes Deck 2 (pour être exact, une partie de l'URL du portail)
],
"en": 1527921725,
"te": 1, #Information gagnante
"pr": 1,
"cu": 0
},
Parmi eux, une liste de 40 caractères alphanumériques ci-dessous
"hs": `(exemple:`
"3.3.6so2A. ‥ Omis ‥ .6t_RI" `` `) est une liste de cartes et un portail Représente une partie de l'URL de.
Utilisez ces informations pour ** la détermination de l'archétype ** et ** obtenir des informations de deck à partir du portail **.
L'archétype est déterminé à l'aide de la liste de 40 cartes obtenue à partir du fichier JSON. La logique utilisée pour le jugement est la même que Article précédent, et le jugement est rendu par ** si la carte-clé est incluse **.
** Exemple: comprend 3 magasins spécialisés d'outils magiques → Magasin spécialisé sorcière **
Effectuez ** Web scraping ** pour collecter des informations sur le nom et le numéro de la carte à partir du portail L'URL du portail a la structure suivante.
** (Exemple: Spellwitch) ** https://shadowverse-portal.com/deckbuilder/create/3?hash=3.3.6so2A.6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6_djc.6_djc.6_djc.5-gka.5-gka.5-gka.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.gPWp2.gPWp2.gPWp2.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6xpaI.5-glM.5-glM.5-glM.6t_RI.6t_RI.6t_RI?lang=ja
Si vous le comparez à la valeur stockée dans
hs ''
du fichier JSON, vous pouvez voir qu'il représente le suivant de l'URL du portail
hash represents`.
Utilisez ceci pour générer l'URL du portail.
Demandez le fichier HTML du portail à partir de l'URL générée et effectuez une analyse structurelle du HTML avec Beautiful Soup. ** Beautiful Soup est une bibliothèque qui extrait des informations à partir de fichiers HTML **.
Concernant le scraping Web du portail, je me suis référé à cet article.
Obtenez les données du deck Shadowverse à l'aide de Beautiful Soup et de l'API Twitter en Python
Examinons de plus près le fichier HTML du portail. [Ici](https://shadowverse-portal.com/deck/3.3.6so2A.6so2A.6so2A.5-gkQ.5-gkQ.5-gkQ.6_X7Q.6_X7Q.6_X7Q.6-Ntw.6_djc.6_djc. 6_djc.6turQ.6turQ.6turQ.6xnsw.6xnsw.6xnsw.6_ZZg.6_ZZg.6_ZZg.6q8sC.6q8sC.6q8sC.6twYy.6twYy.6twYy.6t_RI.6t_RI.6t_RI.5- Le jeu de cartes gPWp2.gPWp2.gPWp2.5-glM.5-glM.5-glM? Lang = ja) sera expliqué à titre d'exemple. Tout d'abord, affichez le code source HTML avec la fonction du navigateur (dans le cas de Chorme, clic droit → afficher la source de la page)
En parcourant les pages, vous trouverez des informations sur le nom de la carte et le nombre de cartes.
example.html
<p class="el-card-list-info-name">
<span class="el-card-list-info-name-text">Lumière de sagesse</span>
</p>
<p class="el-card-list-info-count">×3</p>
<p class="el-card-list-link">
<a
class="el-icon-search is-small tooltipify"
href="/card/100314010"
target="_blank"
data-card-tribe-name="-"
data-card-atk="0"
data-card-evo-atk="0"
data-card-life="0"
data-card-evo-life="0"
data-card-name="Lumière de sagesse"
data-card-skill-disc="Dessiner une carte."
De même, en regardant d'autres cartes, le nom de la carte est el-card-list-info-name-text
et le numéro est ```el-card-list-info-count`` Vous pouvez voir que l'attribut class est donné.
En utilisant la fonction de sélection de Beautiful soup, vous pouvez ** extraire les éléments des attributs de classe et des balises spécifiés à la fois **.
Les dernières données agrégées sont tabulées avec Pandas et représentées graphiquement avec matplotlib.
Importez d'abord les bibliothèques requises.
import.py
import requests
import bs4
import json
import pandas as pd
import sys
Définit une fonction qui détermine l'architype.
Passez les ** informations de classe ** (`` sv_class```) et la ** liste de 40 cartes ** (
`sv_deck```) comme arguments, et triez les archétypes selon la logique de jugement définie. Je vais.
En tant que valeur de retour, le nom architype du résultat du jugement est renvoyé.
archetype.py
#Liste des architypes
arche_dict = {"E":["Reno Seus E", "Amatsu E", "Autre E"],"R": ["Évolution R", "Coopération R", "Autre R"],"W": ["Épeler W", "Magasin spécialisé W", "Arcane W", "Autre W"],"D": ["Jeter D", "Baleine D", "Autre D"],"Nc": ["Meifu Nc", "Funérailles Nc", "Autre Nc"],"V": ["Contrôle V", "Frénésie V", "Autre V"],"B": ["Eira B", "Contrôle B", "Autre B"],"Nm": ["AFNm", "Autre Nm"]}
#Analyse de classe, de type de pont
def deck_arche_analysis(sv_deck, sv_class):
if sv_class == 1: #Elfe
if sv_deck.count("6lZu2") == 3:
return arche_dict["E"][0]
elif sv_deck.count("6pQTI") == 3:
return arche_dict["E"][1]
else:
return arche_dict["E"][2]
elif sv_class == 2: #Royal
if sv_deck.count("6td16") > 1:
return arche_dict["R"][0]
elif sv_deck.count("6_B9A") == 3:
return arche_dict["R"][1]
else:
return arche_dict["R"][2]
elif sv_class == 3: #Sorcière
if sv_deck.count("6_djc") == 3:
return arche_dict["W"][0]
elif sv_deck.count("6q95g") == 3:
return arche_dict["W"][1]
elif sv_deck.count("6t_Rc") == 3:
return arche_dict["W"][2]
else:
return arche_dict["W"][3]
elif sv_class == 4: #Dragon
if sv_deck.count("6yB-y") == 3:
return arche_dict["D"][0]
elif sv_deck.count("6_zhY") == 3:
return arche_dict["D"][1]
else:
return arche_dict["D"][2]
elif sv_class == 5: #Nécromancien
if sv_deck.count("6n7-I") > 1:
return arche_dict["Nc"][0]
elif sv_deck.count("70OYI") == 3:
return arche_dict["Nc"][1]
else:
return arche_dict["Nc"][2]
elif sv_class == 6: #Vampire
if sv_deck.count("6rGOA") == 3:
return arche_dict["V"][0]
elif sv_deck.count("6v1MC") ==3:
return arche_dict["V"][1]
else:
return arche_dict["V"][2]
elif sv_class == 7: #Évêque
if sv_deck.count("6nupS") == 3:
return arche_dict["B"][0]
elif sv_deck.count("6nsN2") == 3:
return arche_dict["B"][1]
else:
return arche_dict["B"][2]
elif sv_class == 8: #Némésis
if sv_deck.count("6zcK2") == 3:
return arche_dict["Nm"][0]
else:
return arche_dict["Nm"][1]
À partir de l'URL du portail, créez une fonction qui génère la combinaison du nom et du nombre de cartes utilisées. En tant que valeur de retour, toutes les paires de nom de carte et de nombre de cartes sont renvoyées sous forme de variables de type dictionnaire.
get_card-list.py
#Obtenez le deck sur le portail
def get_deck(url):
#Demander un fichier html
response = requests.get(url)
#codage
response.encoding = response.apparent_encoding
#analyse html
soup = bs4.BeautifulSoup(response.text, "html.parser")
#Obtenez une liste de noms de cartes
names = soup.select(r".el-card-list-info-name-text")
#Obtenez une liste de feuilles
counts = soup.select(r".el-card-list-info-count")
#{nom de la carte:Nombre de feuilles}Créer un dictionnaire de
deck = {name.text: int(count.text[1:]) for name, count in zip(names, counts)}
return deck
Je me suis référé à cet article pour la fonction permettant d'obtenir la liste de deck à partir du portail.
Obtenez les données du deck Shadowverse à l'aide de Beautiful Soup et de l'API Twitter en Python
Spécifiez le tournoi JCG que vous souhaitez vérifier et obtenez le fichier JSON.
Définissez également arche_search
comme nom d'archétype que vous souhaitez rechercher.
Ceci est comparé au résultat de la fonction de jugement de l'archétype et utilisé pour vérifier s'il s'agit de l'architype souhaité.
json.py
#Entrez le numéro du tournoi JCG
compe_num = input("Veuillez saisir le numéro du tournoi JCG que vous souhaitez rechercher")
#Entrez l'archétype que vous souhaitez rechercher
arche_search = input("Entrez l'archétype que vous souhaitez rechercher")
#URL du fichier JSON du tournoi
jcg_url = "https://sv.j-cg.com/compe/view/entrylist/" + str(compe_num) + "/json"
#Demander un fichier json
res_jcg = requests.get(jcg_url)
#Enregistrer au format texte json
j_txt = json.loads(res_jcg.text)
#Si ce n'est pas le tournoi final, terminez le programme
if not len(j_txt["participants"]) == 32:
sys.exit()
Dans la dernière partie, il est jugé si le numéro de tournoi saisi est le tournoi final. S'il s'agit d'un groupe de qualification, le programme sera interrompu.
analysis.py
#Variable de type dictionnaire qui stocke le nom d'utilisateur, le nom de la carte et le nombre de feuilles
arche_summary = {}
#La partie d'en-tête du portail
dbsp_header = "https://shadowverse-portal.com/deck/"
#Obtenez le nombre de cours
for i in range(len(j_txt["participants"])):
#Confirmation des informations gagnantes
if j_txt["participants"][i]["te"] == 0: #Perdu
continue
elif j_txt["participants"][i]["te"] == 1: #Gagnant
for j in range(2):
#Obtenir des informations sur la classe
class_ij = j_txt["participants"][i]["dk"][j]["cl"]
#Acquisition des informations de la carte
deck_ij = j_txt["participants"][i]["dk"][j]["hs"]
#Déterminer l'archétype à partir des informations de la carte de classe
archetype = deck_arche_analysis(deck_ij, class_ij)
#Lorsque le résultat du jugement correspond à l'architype que vous souhaitez vérifier
if archetype == arche_search:
#Générer l'URL du portail
dbsp_url = dbsp_header+deck_ij
#Obtenez la combinaison du nom de la carte et du nombre de cartes à partir du portail
deck_dict = get_deck(dbsp_url)
#arche_Rédiger des informations en résumé
arche_summary[j_txt["participants"][i]["nm"]] = deck_dict
else:
continue
else:
continue
Enfin, convertissez le résultat agrégé au format Pandas DataFrame et tracez-le avec matplotlib.
** * Si vous souhaitez exécuter le code suivant tel quel, vous devez définir la police japonaise dans matplotlib. ** ** Si vous souhaitez l'exécuter tel quel, téléchargez la police se référant à l'article suivant et placez-la dans le même répertoire que ce fichier python.
graphs.py
#Importer matplotlib
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
#Les deux lignes suivantes concernent les paramètres japonais, vous devez télécharger la police à l'avance
from matplotlib.font_manager import FontProperties
fontprop = FontProperties(fname="ipaexg.ttf")
#Convertir les résultats agrégés au format DataFrame
df_arche_summary = pd.DataFrame(arche_summary)
df_arche_summary = df_arche_summary.fillna(0).astype("int")
#Paramètres de table avancés
fig, ax = plt.subplots()
ax.axis("off")
ax.axis("tight")
tb = ax.table(cellText=df_arche_summary.values,colLabels=df_arche_summary.columns,rowLabels=df_arche_summary.index,colWidths=[0.15]*len(df_arche_summary.columns),loc='center',bbox=[0,0,1,1], cellLoc="center", rowLoc="right")
tb.auto_set_font_size(False)
tb.set_fontsize(8)
for i in range(len(df_arche_summary.columns)):
tb[0,i].set_text_props(font_properties=fontprop, weight='bold', color="w")
tb[0,i].set_facecolor('#2b333b')
for k in range(1,len(df_arche_summary.index)+1):
tb[k,-1].set_text_props(font_properties=fontprop,weight='bold', color="w")
tb[k,-1].set_facecolor('#2b333b')
plt.savefig(arche_search + "_" + compe_num + ".png ",bbox_inches="tight")
** Ligne de commande **
python
$ python JCG_decklist.py
Entrez le numéro du tournoi JCG que vous souhaitez rechercher: 2389
Entrez l'archétype que vous souhaitez rechercher: Spell W
** Résultat d'exécution **
Dans cet article, j'ai présenté comment obtenir la liste des cartes du tournoi final JCG par web scraping. Le code de l'article précédent et le code de cette époque ont beaucoup en commun, vous pouvez donc combiner les deux fonctions en un seul programme.
En passant, la partie du codage qui prend le plus de temps est la mise en page du tableau. Le nombre de colonnes et de lignes a changé à chaque fois, et j'ai eu beaucoup de problèmes avec les paramètres de réglage.
Si vous avez des corrections ou des erreurs concernant le code ou la méthode d'analyse, veuillez nous en informer dans les commentaires.
Recommended Posts