爬取Valve公司旗下Steam的热门游戏排行榜
爬取Valve公司旗下Steam的热门游戏排行榜
一、选题的背景
随着互联网的发展,网络已经深入人们的生活之中。同时,随着经济发展,国民消费水平提高,在精神生活上的消费也日渐增加。所以,网络游戏作为当今年轻人茶余饭后的大占比谈资,年轻人在其上的消费和所花的时间也是非常可观。Valve公司旗下的Steam作为全球最大的综合性数字发行平台之一,它的用户数量及其庞大,本课程设计就是在steam官方网站爬取其当日热门游戏的前二十名,和这二十个游戏的当前在线人数以及当日游戏峰值。
二、主题式网络爬虫设计方案
1.主题式网络爬虫名称
爬取Valve公司旗下Steam的热门游戏排行榜
2.主题式网络爬虫爬取的内容与数据特征分析
爬取steam官网的当日游戏热榜前二十的游戏名,前二十游戏目前在线人数,前二十游戏今日在线人数峰值,从而做出分析对比
3.主题式网络爬虫设计方案概述
爬取steam官网数据统计页面信息并进行数据处理,最后进行可视化对比。
三、主题页面的结构特征分析
1.主题页面的结构与特征分析
网页URL: https://store.steampowered.com
页面截图:
2.Htmls 页面解析
f12打开,寻找所需信息(由于网页数据实时变化,截图与csv文件保存的数值内容有出入)
3.节点(标签)查找方法与遍历方法
使用正则表达式进行匹配
表达式:
四、网络爬虫程序设计
所需要的库:
1 #导入库 2 import requests 3 import re 4 import pandas as pd 5 import numpy as np 6 import csv 7 import matplotlib 8 from matplotlib import pyplot as plt
截图展示:
1.数据爬取与采集
1 #爬取页面源代码 2 url = "https://store.steampowered.com/stats/" 3 4 #写入请求标头,防止网站反爬 5 headers={ 6 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43" 7 } 8 9 resp = requests.get(url,headers=headers) 10 print(resp.text)
打印html:
1 #解析数据 2 #正则表达式 3 4 obj = re.compile('<tr class="player_count_row".*?<span class="currentServers">(?P<now>.*?)' 5 '</span>.*?<span class="currentServers">(?P<today>.*?)' 6 '</span>.*?<a class="gameLink" onmouseover="GameHover.*?">(?P<name>.*?)</a>', re.S) 7 8 #开始匹配 9 10 result = obj.finditer(page_content) 11 f = open("steam数据统计.csv",mode="w",encoding="utf-8",newline="") 12 csvwriter = csv.writer(f) 13 14 for it in result: 15 #print(it.group("now")) 16 #print(it.group("today")) 17 #print(it.group("name")) 18 dic = it.groupdict() #整理成字典的格式 19 csvwriter.writerow(dic.values()) 20 21 # 将打开的文件关闭 22 f.close() 23 24 print("over!爬取完毕!")
附图:
2.对数据进行保存处理
源码:
1 file_path = "C:/Users/EVA/Desktop/steam数据.csv" 2 3 df = pd.read_csv(file_path,header=None) 4 print(df.info()) 5 df.columns = ['Game name','Todays peak','currently online'] 6 #打印表格 7 df
输出表格(【game name:游戏名】 【today's peak:今日峰值】【currently online:当前在线】)
3.绘制折线图:
1 from matplotlib import pyplot as plt 2 #指定文件名,然后使用 with open() as 打开 3 filename = 'C:/Users/EVA/Desktop/steam数据.csv' 4 5 with open('C:/Users/EVA/Desktop/steam数据.csv','r',encoding='UTF-8') as f: 6 #创建一个阅读器:将f传给csv.reader 7 reader = csv.reader(f) 8 #使用csv的next函数,将reader传给next,将返回文件的下一行 9 header_row = next(reader) 10 11 for index, column_header in enumerate(header_row): 12 print(index, column_header) 13 14 highs =[] 15 for row in reader: 16 highs.append(row[1]) 17 #print(highs) 18 #绘制图形 19 fig = plt.figure(dpi=128, figsize=(10,6)) 20 plt.plot(highs,c='c') 21 #设置图形的格式 22 plt.title("difference summary", fontsize=16) 23 plt.xlabel('namber of games',fontsize=16) 24 plt.ylabel("namber of people", fontsize=16) 25 plt.tick_params(axis='both', which="major", labelsize=16) 26 #打印图片 27 plt.show()
输出下图:
4.绘制条形图:
目前在线人数:
1 #设置中文显示,解决乱码问题 2 font = {'family' : 'MicroSoft YaHei', 3 'weight': 'bold', 4 'size': '12'} 5 matplotlib.rc("font",**font) 6 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 7 8 #设置图形大小 9 plt.figure(figsize=(20,13),dpi=80) 10 #添加描述信息 11 plt.xlabel("当前在线人数") 12 plt.ylabel("游戏名") 13 plt.title("steam游戏当前在线人数汇总表") 14 plt.barh(range(len(df['Game name'])), 15 df['currently online'], 16 height=0.3) 17 18 plt.yticks(range(len(df['Game name'])), 19 df['Game name']) 20 plt.show()
今日峰值人数:
1 #设置中文显示,解决乱码问题 2 font = {'family' : 'MicroSoft YaHei', 3 'weight': 'bold', 4 'size': '12'} 5 matplotlib.rc("font",**font) 6 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 7 8 #设置图形大小 9 plt.figure(figsize=(20,13),dpi=80) 10 #添加描述信息 11 plt.xlabel("当日在线人数峰值") 12 plt.ylabel("游戏名") 13 plt.title("当日在线人数峰值汇总表") 14 plt.barh(range(len(df['Game name'])), 15 df['Todays peak'], 16 height=0.3,color='r') 17 18 plt.yticks(range(len(df['Game name'])), 19 df['Game name']) 20 plt.show()
输出图片:
5.绘制柱状图:
1 #设置图形大小 2 plt.figure(figsize=(20,13),dpi=80) 3 4 #设置中文显示,解决乱码问题 5 font = {'family' : 'MicroSoft YaHei', 6 'weight': 'bold', 7 'size': '24'} 8 matplotlib.rc("font",**font) 9 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 10 11 #统计在线人数分布 12 def xl_Dis(): 13 pr = pd.read_csv('C:/Users/EVA/Desktop/steam数据.csv') 14 pr1 = pd.read_csv('C:/Users/EVA/Desktop/steam数据.csv', low_memory=False) 15 print("在线人数分布:") 16 print() 17 xl = [] 18 for i in pr['Todays peak']: 19 xl.append(i) 20 xl1=[] 21 xl2=[] 22 xl3=[] 23 xl4=[] 24 for i in xl: 25 if 40000<i<60000: 26 xl1.append(i) 27 elif 60000<i<100000: 28 xl2.append(i) 29 elif 170000<i<200000: 30 xl3.append(i) 31 elif 200000<i<1000000: 32 xl4.append(i) 33 34 35 index=['40000-60000','60000-100000','170000-200000','200000-1000000'] 36 values=[len(xl1),len(xl2),len(xl3),len(xl4)] 37 plt.bar(index,values) 38 39 plt.show() 40 41 if __name__=="__main__": 42 xl_Dis()
输出图片:
(可以看出不同人数段的游戏数量)
6.绘制人数峰值散点图:
1 #设置图形大小 2 plt.figure(figsize=(20,8),dpi=80) 3 4 #设置中文显示,解决乱码问题 5 font = {'family' : 'MicroSoft YaHei', 6 'weight': 'bold', 7 'size': '24'} 8 matplotlib.rc("font",**font) 9 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 10 11 #添加描述信息 12 plt.xlabel("游戏名") 13 plt.ylabel("峰值人数 单位(人)") 14 plt.title("12月25日steam热门游戏前二十名在线人数峰值") 15 16 #调整x轴,翻转90度 17 plt.xticks(rotation=90) 18 19 plt.scatter(df['Game name'], 20 df['Todays peak']) 21 22 plt.savefig('12月25日steam热门游戏前二十名在线人数峰值.jpg') 23 24 plt.show()
输出图片:
7.绘制扇形图
1 #查看中位数、最大最小值 2 print(df.describe())
1 edu=[len(df[df["Todays peak"]<100000.00]["Todays peak"]), 2 len(df[df["Todays peak"]>100000.00][df["Todays peak"]<200000.00]["Todays peak"]), 3 len(df[df["Todays peak"]>200000.00][df["Todays peak"]<300000.00]["Todays peak"]), 4 len(df[df["Todays peak"]>300000.00]["Todays peak"])] 5 6 plt.rcParams['font.sans-serif']=['Microsoft YaHei'] 7 plt.rcParams['axes.unicode_minus']=False 8 plt.axes(aspect='equal') 9 10 labels = ["steam今日峰值小于10万", "steam今日峰值小于20万大于10万", "steam今日峰值小于30万大于20万", "steam今日峰值大于30万"] 11 explode = [0.1, 0, 0, 0] 12 colors = ['grey', 'silver', 'lightgray', 'whitesmoke'] 13 plt.pie(edu, 14 explode=explode, 15 labels=labels, 16 colors=colors, 17 autopct='%.2f%%', 18 pctdistance=0.8, 19 labeldistance=1.1, 20 startangle=180, 21 radius=1.2, 22 counterclock=False, 23 wedgeprops={'linewidth':1.5, 'edgecolor':'white'}, 24 textprops={'fontsize':10, 'color':'black'}, 25 ) 26 #添加标题 27 plt.title('steam今日游戏在线峰值分布') 28 29 #数据持久化 30 plt.savefig('steam今日游戏在线峰值分布.jpg') 31 32 plt.show()
输出图片:
8.数据持久化
9.代码汇总
1 #导入库 2 import requests 3 import re 4 import pandas as pd 5 import numpy as np 6 import csv 7 import matplotlib 8 from matplotlib import pyplot as plt 9 10 #爬取页面源代码 11 url = "https://store.steampowered.com/stats/" 12 13 #写入请求标头,防止网站反爬 14 headers={ 15 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43" 16 } 17 18 resp = requests.get(url,headers=headers) 19 page_content = resp.text 20 resp.close() 21 22 #解析数据 23 #正则表达式 24 25 obj = re.compile('<tr class="player_count_row".*?<span class="currentServers">(?P<now>.*?)' 26 '</span>.*?<span class="currentServers">(?P<today>.*?)' 27 '</span>.*?<a class="gameLink" onmouseover="GameHover.*?">(?P<name>.*?)</a>', re.S) 28 29 #开始匹配 30 31 result = obj.finditer(page_content) 32 f = open("steam数据统计.csv",mode="w",encoding="utf-8",newline="") 33 csvwriter = csv.writer(f) 34 35 for it in result: 36 #print(it.group("now")) 37 #print(it.group("today")) 38 #print(it.group("name")) 39 dic = it.groupdict() #整理成字典的格式 40 csvwriter.writerow(dic.values()) 41 42 # 将打开的文件关闭 43 f.close() 44 45 print("over!爬取完毕!") 46 47 48 file_path = "C:/Users/EVA/Desktop/steam数据.csv" 49 50 df = pd.read_csv(file_path,header=None) 51 print(df.info()) 52 df.columns = ['Game name','Todays peak','currently online'] 53 #打印表格 54 df 55 56 57 #导入csv模块 58 from matplotlib import pyplot as plt 59 #指定文件名,然后使用 with open() as 打开 60 filename = 'C:/Users/EVA/Desktop/steam数据.csv' 61 62 with open('C:/Users/EVA/Desktop/steam数据.csv','r',encoding='UTF-8') as f: 63 #创建一个阅读器:将f传给csv.reader 64 reader = csv.reader(f) 65 #使用csv的next函数,将reader传给next,将返回文件的下一行 66 header_row = next(reader) 67 68 for index, column_header in enumerate(header_row): 69 print(index, column_header) 70 71 highs =[] 72 for row in reader: 73 highs.append(row[1]) 74 #print(highs) 75 76 #绘制图形 77 fig = plt.figure(dpi=128, figsize=(10,6)) 78 plt.plot(highs,c='c') 79 #设置图形的格式 80 plt.title("difference summary", fontsize=16) 81 plt.xlabel('namber of games',fontsize=16) 82 plt.ylabel("namber of people", fontsize=16) 83 plt.tick_params(axis='both', which="major", labelsize=16) 84 #打印图片 85 plt.show() 86 87 88 #设置中文显示,解决乱码问题 89 font = {'family' : 'MicroSoft YaHei', 90 'weight': 'bold', 91 'size': '12'} 92 matplotlib.rc("font",**font) 93 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 94 95 #绘制在线人数汇总表 96 #设置图形大小 97 plt.figure(figsize=(20,13),dpi=80) 98 #添加描述信息 99 plt.xlabel("当前在线人数") 100 plt.ylabel("游戏名") 101 plt.title("steam游戏当前在线人数汇总表") 102 plt.barh(range(len(df['Game name'])), 103 df['currently online'], 104 height=0.3) 105 106 plt.yticks(range(len(df['Game name'])), 107 df['Game name']) 108 109 #数据持久化 110 plt.savefig('steam游戏当前在线人数汇总表.jpg') 111 112 plt.show() 113 114 #绘制峰值汇总表 115 font = {'family' : 'MicroSoft YaHei', 116 'weight': 'bold', 117 'size': '12'} 118 matplotlib.rc("font",**font) 119 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 120 121 #设置图形大小 122 plt.figure(figsize=(20,13),dpi=80) 123 #添加描述信息 124 plt.xlabel("当日在线人数峰值") 125 plt.ylabel("游戏名") 126 plt.title("当日在线人数峰值汇总表") 127 plt.barh(range(len(df['Game name'])), 128 df['Todays peak'], 129 height=0.3,color='r') 130 131 plt.yticks(range(len(df['Game name'])), 132 df['Game name']) 133 134 #数据持久化 135 plt.savefig('当日在线人数峰值汇总表.jpg') 136 plt.show() 137 138 #绘制峰值柱状图 139 plt.figure(figsize=(20,13),dpi=80) 140 font = {'family' : 'MicroSoft YaHei', 141 'weight': 'bold', 142 'size': '24'} 143 matplotlib.rc("font",**font) 144 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 145 146 #统计在线人数分布 147 def xl_Dis(): 148 pr = pd.read_csv('C:/Users/EVA/Desktop/steam数据.csv') 149 pr1 = pd.read_csv('C:/Users/EVA/Desktop/steam数据.csv', low_memory=False) 150 print("在线人数分布:") 151 print() 152 xl = [] 153 for i in pr['Todays peak']: 154 xl.append(i) 155 xl1=[] 156 xl2=[] 157 xl3=[] 158 xl4=[] 159 for i in xl: 160 if 40000<i<60000: 161 xl1.append(i) 162 elif 60000<i<100000: 163 xl2.append(i) 164 elif 170000<i<200000: 165 xl3.append(i) 166 elif 200000<i<1000000: 167 xl4.append(i) 168 169 170 index=['40000-60000','60000-100000','170000-200000','200000-1000000'] 171 values=[len(xl1),len(xl2),len(xl3),len(xl4)] 172 plt.bar(index,values) 173 174 #数据持久化 175 plt.savefig('在线人数分布.jpg') 176 177 plt.show() 178 179 if __name__=="__main__": 180 xl_Dis() 181 182 183 plt.figure(figsize=(20,8),dpi=80) 184 #设置字体,字体大小等数据 185 font = {'family' : 'MicroSoft YaHei', 186 'weight': 'bold', 187 'size': '24'} 188 matplotlib.rc("font",**font) 189 matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 190 191 #添加描述信息 192 plt.xlabel("游戏名") 193 plt.ylabel("峰值人数 单位(人)") 194 plt.title("12月25日steam热门游戏前二十名在线人数峰值") 195 196 #调整x轴,翻转90度 197 plt.xticks(rotation=90) 198 199 plt.scatter(df['Game name'], 200 df['Todays peak']) 201 202 203 #数据持久化 204 plt.savefig('12月25日steam热门游戏前二十名在线人数峰值.jpg') 205 206 plt.show() 207 208 #绘制扇形图 209 210 #查看中位数、最大最小值 211 print(df.describe()) 212 213 edu=[len(df[df["Todays peak"]<100000.00]["Todays peak"]), 214 len(df[df["Todays peak"]>100000.00][df["Todays peak"]<200000.00]["Todays peak"]), 215 len(df[df["Todays peak"]>200000.00][df["Todays peak"]<300000.00]["Todays peak"]), 216 len(df[df["Todays peak"]>300000.00]["Todays peak"])] 217 218 plt.rcParams['font.sans-serif']=['Microsoft YaHei'] 219 plt.rcParams['axes.unicode_minus']=False 220 plt.axes(aspect='equal') 221 222 labels = ["steam今日峰值小于10万", "steam今日峰值小于20万大于10万", "steam今日峰值小于30万大于20万", "steam今日峰值大于30万"] 223 explode = [0.1, 0, 0, 0] 224 colors = ['grey', 'silver', 'lightgray', 'whitesmoke'] 225 plt.pie(edu, 226 explode=explode, 227 labels=labels, 228 colors=colors, 229 autopct='%.2f%%', 230 pctdistance=0.8, 231 labeldistance=1.1, 232 startangle=180, 233 radius=1.2, 234 counterclock=False, 235 wedgeprops={'linewidth':1.5, 'edgecolor':'white'}, 236 textprops={'fontsize':10, 'color':'black'}, 237 ) 238 #添加标题 239 plt.title('steam今日游戏在线峰值分布') 240 241 #数据持久化 242 plt.savefig('steam今日游戏在线峰值分布.jpg') 243 244 #输出图片 245 plt.show()
五、总结
1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?
(1)steam平台的在线峰值人数庞大,游戏多种多样
(2)其中两款游戏,射击游戏cs:go和moba游戏dota2不管实时人数还是人数峰值都是远超其他游戏
(3)其中人数小于10万的游戏占绝大部分,高达70%。效果达到了预期的目标
2.在完成此设计过程中,得到哪些收获?以及要改进的建议?
通过此次课程设计,我能更加熟练的运用爬虫知识来获取信息,了解了python对大数据处理的优势。报告完成过程中遇到了许多问题,暴露了学习的不扎实,其中可视化的问题较多,许多图片的输出都达不到预期的效果,但是在不断的思考和尝试下,这些问题也都迎刃而解了。还需要多学习、练习,多动手尝试。