英雄联盟角色数据可视化
前言
电子竞技在当今社会越来越来受欢迎,同时电子竞技也成了奥运会项目之一。英雄联盟在其中也是最受欢迎的几款游戏之一,所以我爬取了其中的角色数据,对其进行可视化处理。
爬虫设计方案
1. 爬虫名称
英雄联盟角色数据可视化
2. 爬取内容与数据特征分析
目标网站是英雄联盟官网 https://lol.qq.com/main.shtml,其原理主要是通过Requests获取Json请求,从而爬取数据。
3. 方案概述
分析网站页面结构,找到爬取数据的位置,根据不同的数据制定不同的爬取方法,将爬取的数据保存成csv文件,然后再将csv文件里的数据进行可视化处理。
第一步 分析网站 第二步 发送请求并获取Json数据 第三步 获取数据 第四步 绘制柱状图等
分析网站
通过浏览器“审查元素”查看源代码及“网络”反馈的消息,如下图所示:
网站html页面结构分析
爬虫程序设计
1. 数据的爬取
(1) 数据的爬取
#爬取数据 import requests from bs4 import BeautifulSoup import json head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) r.encoding='utf-8' data=json.loads(r.text) #输出数据 print(data)
(2) 获取数据
#爬取数据 import requests from bs4 import BeautifulSoup import json head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) r.encoding='utf-8' data=json.loads(r.text) #输出数据 print(data) #创建空列表 rank=[] name=[] names=[] difficult=[] g=[] f=[] m=[] o=[] money=[] a=data['hero'] #提取数据 for i in a: try: rank.append(i['heroId']) name.append(i['name']) names.append(i['title']) difficult.append(i['difficulty']) g.append(i['attack']) f.append(i['defense']) m.append(i['magic']) o.append(i['roles']) money.append(i['goldPrice']) except: pass print(rank) print(name) print(names) print(difficult) print(g) print(f) print(m) print(o) print(money)
(3) 保存数据
import requests from bs4 import BeautifulSoup import json head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) r.encoding='utf-8' data=json.loads(r.text) #输出数据 print(data) #创建空列表 rank=[] name=[] names=[] difficult=[] g=[] f=[] m=[] o=[] money=[] a=data['hero'] #提取数据 for i in a: try: rank.append(i['heroId']) name.append(i['name']) names.append(i['title']) difficult.append(i['difficulty']) g.append(i['attack']) f.append(i['defense']) m.append(i['magic']) o.append(i['roles']) money.append(i['goldPrice']) except: pass print(rank) print(name) print(names) print(difficult) print(g) print(f) print(m) print(o) print(money) #转为数据框,保存为CSV文件 import pandas as pd d={'排名':rank,'职业':o,'名称':name,'英雄名':names,'攻击':g,'防御力':f,'法力':m,'难度':difficult,'金币':money} df=pd.DataFrame(d) df.to_csv('D:/新建文件夹/英雄联盟.csv',index=False)
2. 数据清洗与处理
(1)通过查看数据的简要信息
#查看数据的简要信息 df.describe()
(2)通过pandas库的isnull()方法查看是否有空值
#判断是否有空值 df['攻击'].isnull().value_counts()
df['防御力'].isnull().value_counts()
df['法力'].isnull().value_counts()
3. 数据可视化分析
import requests from bs4 import BeautifulSoup import json head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) r.encoding='utf-8' data=json.loads(r.text) #输出数据 print(data) #创建空列表 rank=[] name=[] names=[] difficult=[] g=[] f=[] m=[] o=[] money=[] a=data['hero'] #提取数据 for i in a: try: rank.append(i['heroId']) name.append(i['name']) names.append(i['title']) difficult.append(i['difficulty']) g.append(i['attack']) f.append(i['defense']) m.append(i['magic']) o.append(i['roles']) money.append(i['goldPrice']) except: pass print(rank) print(name) print(names) print(difficult) print(g) print(f) print(m) print(o) print(money) #画折线图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=rank[:30] y=f[:30] plt.scatter(x,y) plt.plot(x,y)
#画柱状图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=name[0:30] y=f[0:30] plt.bar(x,y,) plt.xlabel('名字') plt.ylabel('防御力') plt.show()
#画柱状图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=name[0:20] y=m[0:20] plt.bar(x,y,) plt.xlabel('名字') plt.ylabel('法力') plt.show()
#画柱状图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=name[0:20] y=g[0:20] plt.bar(x,y,) plt.xlabel('名字') plt.ylabel('攻击力') plt.show()
#画柱状图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=name[0:20] y=difficult[0:20] plt.bar(x,y,) plt.xlabel('名字') plt.ylabel('难度') plt.show()
#画柱状图 import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False x=name[0:20] y=money[0:20] plt.bar(x,y,) plt.xlabel('名字') plt.ylabel('金币') plt.show()
#画雷达图 # coding=utf-8 import numpy as np import matplotlib.pyplot as plt #消除中文乱码 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False results = [{"防御力": f[0], "攻击力": g[0], "法力": m[0], "难度":difficult[0] , "金币":int(money[0])/1000}] data_length = len(results[0]) # 将极坐标根据数据长度进行等分 angles = np.linspace(0, 2*np.pi, data_length, endpoint=False) labels = [key for key in results[0].keys()] score = [[v for v in result.values()] for result in results] # 使雷达图数据封闭 score_a = np.concatenate((score[0], [score[0][0]])) angles = np.concatenate((angles, [angles[0]])) labels = np.concatenate((labels, [labels[0]])) # 设置图形的大小 fig = plt.figure(figsize=(3,6), dpi=200) # 新建一个子图 ax = plt.subplot(111, polar=True) # 绘制雷达图 ax.plot(angles,score_a,color='r') # 设置雷达图中每一项的标签显示 ax.set_thetagrids(angles*180/np.pi, labels) # 设置雷达图的0度起始位置 ax.set_theta_zero_location('N') # 设置雷达图的坐标刻度范围 ax.set_rlim(0,10) # 设置雷达图的坐标值显示角度,相对于起始角度的偏移量 ax.set_rlabel_position(270) ax.set_title("角色数据") plt.legend(["安妮"],loc='best') plt.show()
1 #爬取数据 2 import requests 3 from bs4 import BeautifulSoup 4 import json 5 head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} 6 r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) 7 r.encoding='utf-8' 8 data=json.loads(r.text) 9 10 #输出数据 11 print(data) 12 13 #创建空列表 14 rank=[] 15 name=[] 16 names=[] 17 difficult=[] 18 g=[] 19 f=[] 20 m=[] 21 o=[] 22 money=[] 23 a=data['hero'] 24 #提取数据 25 for i in a: 26 try: 27 rank.append(i['heroId']) 28 name.append(i['name']) 29 names.append(i['title']) 30 difficult.append(i['difficulty']) 31 g.append(i['attack']) 32 f.append(i['defense']) 33 m.append(i['magic']) 34 o.append(i['roles']) 35 money.append(i['goldPrice']) 36 except: 37 pass 38 39 print(rank) 40 print(name) 41 print(names) 42 print(difficult) 43 print(g) 44 print(f) 45 print(m) 46 print(o) 47 print(money) 48 49 #转为数据框,保存为CSV文件 50 #爬取数据 51 import requests 52 from bs4 import BeautifulSoup 53 import json 54 head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} 55 r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) 56 r.encoding='utf-8' 57 data=json.loads(r.text) 58 59 #输出数据 60 print(data) 61 62 #创建空列表 63 rank=[] 64 name=[] 65 names=[] 66 difficult=[] 67 g=[] 68 f=[] 69 m=[] 70 o=[] 71 money=[] 72 a=data['hero'] 73 #提取数据 74 for i in a: 75 try: 76 rank.append(i['heroId']) 77 name.append(i['name']) 78 names.append(i['title']) 79 difficult.append(i['difficulty']) 80 g.append(i['attack']) 81 f.append(i['defense']) 82 m.append(i['magic']) 83 o.append(i['roles']) 84 money.append(i['goldPrice']) 85 except: 86 pass 87 import pandas as pd 88 d={'排名':rank,'职业':o,'名称':name,'英雄名':names,'攻击':g,'防御力':f,'法力':m,'难度':difficult,'金币':money} 89 df=pd.DataFrame(d) 90 df.to_csv('D:/新建文件夹/英雄联盟.csv',index=False) 91 df 92 93 #查看数据的简要信息 94 df.describe() 95 96 #判断是否有空值 97 df['攻击'].isnull().value_counts() 98 99 df['防御力'].isnull().value_counts() 100 101 df['法力'].isnull().value_counts() 102 103 #画折线图 104 #爬取数据 105 import requests 106 from bs4 import BeautifulSoup 107 import json 108 head={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400'} 109 r=requests.get('https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js',headers=head) 110 r.encoding='utf-8' 111 data=json.loads(r.text) 112 113 #输出数据 114 print(data) 115 116 #创建空列表 117 rank=[] 118 name=[] 119 names=[] 120 difficult=[] 121 g=[] 122 f=[] 123 m=[] 124 o=[] 125 money=[] 126 a=data['hero'] 127 #提取数据 128 for i in a: 129 try: 130 rank.append(i['heroId']) 131 name.append(i['name']) 132 names.append(i['title']) 133 difficult.append(i['difficulty']) 134 g.append(i['attack']) 135 f.append(i['defense']) 136 m.append(i['magic']) 137 o.append(i['roles']) 138 money.append(i['goldPrice']) 139 except: 140 pass 141 import matplotlib.pyplot as plt 142 #消除中文乱码 143 plt.rcParams['font.sans-serif']=['SimHei'] 144 plt.rcParams['axes.unicode_minus']=False 145 146 x=rank[:30] 147 y=f[:30] 148 plt.scatter(x,y) 149 plt.plot(x,y) 150 151 152 153 #画柱状图 154 import matplotlib.pyplot as plt 155 #消除中文乱码 156 plt.rcParams['font.sans-serif']=['SimHei'] 157 plt.rcParams['axes.unicode_minus']=False 158 159 x=name[0:30] 160 y=f[0:30] 161 plt.bar(x,y,) 162 plt.xlabel('名字') 163 plt.ylabel('防御力') 164 plt.show() 165 166 #画柱状图 167 import matplotlib.pyplot as plt 168 #消除中文乱码 169 plt.rcParams['font.sans-serif']=['SimHei'] 170 plt.rcParams['axes.unicode_minus']=False 171 172 x=name[0:20] 173 y=m[0:20] 174 plt.bar(x,y,) 175 plt.xlabel('名字') 176 plt.ylabel('法力') 177 plt.show() 178 179 #画柱状图 180 import matplotlib.pyplot as plt 181 #消除中文乱码 182 plt.rcParams['font.sans-serif']=['SimHei'] 183 plt.rcParams['axes.unicode_minus']=False 184 185 x=name[0:20] 186 y=g[0:20] 187 plt.bar(x,y,) 188 plt.xlabel('名字') 189 plt.ylabel('攻击力') 190 plt.show() 191 192 #画柱状图 193 import matplotlib.pyplot as plt 194 #消除中文乱码 195 plt.rcParams['font.sans-serif']=['SimHei'] 196 plt.rcParams['axes.unicode_minus']=False 197 198 x=name[0:20] 199 y=difficult[0:20] 200 plt.bar(x,y,) 201 plt.xlabel('名字') 202 plt.ylabel('难度') 203 plt.show() 204 205 #画柱状图 206 import matplotlib.pyplot as plt 207 #消除中文乱码 208 plt.rcParams['font.sans-serif']=['SimHei'] 209 plt.rcParams['axes.unicode_minus']=False 210 211 x=name[0:20] 212 y=money[0:20] 213 plt.bar(x,y,) 214 plt.xlabel('名字') 215 plt.ylabel('金币') 216 plt.show() 217 218 #画雷达图 219 # coding=utf-8 220 import numpy as np 221 import matplotlib.pyplot as plt 222 #消除中文乱码 223 plt.rcParams['font.sans-serif']=['SimHei'] 224 plt.rcParams['axes.unicode_minus']=False 225 226 results = [{"防御力": f[0], "攻击力": g[0], "法力": m[0], "难度":difficult[0] , "金币":int(money[0])/1000}] 227 data_length = len(results[0]) 228 # 将极坐标根据数据长度进行等分 229 angles = np.linspace(0, 2*np.pi, data_length, endpoint=False) 230 labels = [key for key in results[0].keys()] 231 score = [[v for v in result.values()] for result in results] 232 # 使雷达图数据封闭 233 score_a = np.concatenate((score[0], [score[0][0]])) 234 angles = np.concatenate((angles, [angles[0]])) 235 labels = np.concatenate((labels, [labels[0]])) 236 # 设置图形的大小 237 fig = plt.figure(figsize=(3,6), dpi=200) 238 # 新建一个子图 239 ax = plt.subplot(111, polar=True) 240 # 绘制雷达图 241 ax.plot(angles,score_a,color='r') 242 # 设置雷达图中每一项的标签显示 243 ax.set_thetagrids(angles*180/np.pi, labels) 244 # 设置雷达图的0度起始位置 245 ax.set_theta_zero_location('N') 246 # 设置雷达图的坐标刻度范围 247 ax.set_rlim(0,10) 248 # 设置雷达图的坐标值显示角度,相对于起始角度的偏移量 249 ax.set_rlabel_position(270) 250 ax.set_title("角色数据") 251 plt.legend(["安妮"],loc='best') 252 plt.show()
总结:这组数据虽然在数据元素上没有任何联系,但在处理这组数据上我任然学到了很多有用的东西,让我终生受用受益无穷。
通过这次程序设计我学会了画雷达图,对网络爬虫有了更深刻的学习。这次程序设计使我认识到了我很多的不足,在接下来的学习中我会不断完善这些不足,努力提高自己。让我知道了“三人行必有我师焉”的道理,让我知道了我与他人差距。这会让我有不断挑战自我的动力,让我奋发向前。