爬取Valve公司旗下Steam的热门游戏排行榜

爬取Valve公司旗下Steam的热门游戏排行榜

 

 

 一、选题的背景

       随着互联网的发展,网络已经深入人们的生活之中。同时,随着经济发展,国民消费水平提高,在精神生活上的消费也日渐增加。所以,网络游戏作为当今年轻人茶余饭后的大占比谈资,年轻人在其上的消费和所花的时间也是非常可观。Valve公司旗下的Steam作为全球最大的综合性数字发行平台之一,它的用户数量及其庞大,本课程设计就是在steam官方网站爬取其当日热门游戏的前二十名,和这二十个游戏的当前在线人数以及当日游戏峰值。

二、主题式网络爬虫设计方案

    1.主题式网络爬虫名称

        爬取Valve公司旗下Steam的热门游戏排行榜

    2.主题式网络爬虫爬取的内容与数据特征分析

        爬取steam官网的当日游戏热榜前二十的游戏名,前二十游戏目前在线人数,前二十游戏今日在线人数峰值,从而做出分析对比

    3.主题式网络爬虫设计方案概述

        爬取steam官网数据统计页面信息并进行数据处理,最后进行可视化对比。

 

三、主题页面的结构特征分析

    1.主题页面的结构与特征分析

       网页URL: https://store.steampowered.com

                          欢迎来到 Steam (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对大数据处理的优势。报告完成过程中遇到了许多问题,暴露了学习的不扎实,其中可视化的问题较多,许多图片的输出都达不到预期的效果,但是在不断的思考和尝试下,这些问题也都迎刃而解了。还需要多学习、练习,多动手尝试。

posted @ 2021-12-28 03:02  松阿仔  阅读(420)  评论(0)    收藏  举报