3DM热门单机游戏排行榜的爬取和数据分析

 

(一)、选题的背景

3dm是一个综合游戏门户网站,拥有单机用户最多、最活跃的论坛,最初由一批日语高手和游戏爱好者组成的依靠网站广告生存的民间组织,成立于1999-2000年。几经波折后成为国内最大的集游戏资讯、游戏首发、游戏汉化、未加密补丁发布的游戏综合门户网站,网站以讨论游戏内容和提供首发游戏资源下载为主。3dm拥有国内最强的游戏汉化团队、游戏内容制作团队。网站常年致力于为游戏玩家提供最全、最新、最快的单机游戏及电玩游戏资讯、内容和服务,并以让玩家在游戏上市后最短时间内体验到国外大作的高质量中文版本为目标。

随着科技的发展,游戏在年轻人群体里得到越来越多的青睐,而热门的游戏排行榜可以体现各个游戏的指标,可以让玩家更好选择游戏

(二)、主题式网络爬虫设计方案(10 分)

1.主题式网络爬虫名称:

爬取3DM热门单机游戏排行榜数据并数据分析及可视化

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

对3DM热门单机游戏排行榜的“排名”,“游戏名”,“游戏类型”,“评分”四个数据进行爬取

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

实现思路:进入3DM游戏官网,进入热门单机游戏排行榜,进入网页开发人员工具,得到网页源代码,查找所需标签的代码,进行数据采集,完成后对数据进行相应的分析整理并存入文档中。读取文件进行数据清洗和数据可视化,绘制图形进行数据分析。接下来分析排行和时长的数据拟合分析,最后进行数据持久化。

技术难点:爬取信息时对标签的筛选,做数据分析,即求回归系数,因为标题是文字,无法与数字作比较,需要把标题这一列删除,不然输出结果经常会显示超出列表范围。

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

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

通过对页面结构的分析,发现<div class="phlist">元素中,发现所需要的数据。并进行查找,在标签<a>,<class="infolis">,<span>,<class="num">分别找到游戏名,游戏类型,评分,排名的数据

 url为https://www.3dmgame.com/phb.html

网址首页

 

 

 

 

 

 2.Htmls 页面解析

 通过查找网页源代码,浏览其中元素,并对其中元素进行解析

 

 

 

 

3.节点(标签)查找方法与遍历方法

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(四)、网络爬虫程序设计(60 分)

1.数据爬取与采集

 

 1 #导入相关库
 2 import requests
 3 #引入pandas用于数据可视化
 4 import pandas as pd
 5 import numpy as np
 6 import matplotlib.pyplot as plt
 7 import matplotlib
 8 import csv
 9 import scipy as sp
10 import seaborn as sns
11 from sklearn.linear_model import LinearRegression
12 from bs4 import BeautifulSoup
13 from pandas import DataFrame
14 from scipy.optimize import leastsq
15 import requests
16 from bs4 import BeautifulSoup
17 #3DM热门单机游戏排行榜
18 r = requests.get("https://www.3dmgame.com/phb.html")
19 r.encoding = "utf-8"    #为了简化代码,没有考虑异常情况。
20 soup = BeautifulSoup(r.text,'html.parser')    #soup就是一个BeautifulSoup对象。
21 #type(soup)
22 print(soup.prettify())#基于bs4库HTML的格式输出,让页面更友好的显示

 

 

 

 1 #爬取数据
 2 #爬取游戏名
 3 h=[]
 4 for n in soup.find_all("a",class_="")[33:63]:
 5     h.append(n.get_text().strip())
 6         
 7 h
 8 
 9 #爬取排名
10 c=[]
11 for n in soup.find_all(class_="num"):
12     c.append(n.get_text().strip())        
13 
14 c
15 
16 #爬取评分
17 b=[]
18 for i in soup.find_all('span', class_='')[8:-7:2]:
19     b.append(i.get_text().strip())
20 
21 b
22 
23 #爬取游戏类型
24 d=[]
25 for i in soup.find_all('li', class_='')[12:-3:7]:
26     d.append(i.get_text().strip())
27 
28 e=d
29 e

 

 

 

 

 

 

 

 

 

 1 #将数据整理成表格
 2 print('{:^55}'.format('3DM热门单机游戏排行榜'))
 3 print('{:^5}\t{:^40}\t{:^30}\t{:^10}'.format('排名', '游戏名', '游戏类型', '评分'))
 4 num = 20
 5 lst = []
 6 for i in range(num):
 7     print('{:^5}\t{:^40}\t{:^30}\t{:^10}'.format(c[i], h[i], e[i],b[i]))
 8     lst.append([c[i],h[i], d[i],b[i]])
 9 df = pd.DataFrame(lst,columns=['排名', '游戏名', '游戏类型', '评分'])
10 
11 #将数据存入excel表
12 rank = r'3DM热门单机游戏排行榜.xlsx'
13 df.to_excel(rank)

 

 

 

2.对数据进行清洗和处理

 1 #数据清洗
 2 
 3 #重复值处理
 4 print(df.duplicated())
 5 
 6 #统计空值
 7 print(df.isnull().sum())  #返回0则没有空值
 8 
 9 #缺失值处理
10 print(df[df.isnull().values==True]) #返回无缺失值
11 
12 #用describe()命令显示描述性统计指标
13 print(df.describe())

 

 

 

4.数据分析与可视化

 1 #选择排名和评分两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
 2 colnames=[" ","排名","名称","评分"]
 3 df = pd.read_excel('C:/Users/方瑞行/3DM热门单机游戏排行榜.xlsx')
 4 # 用来正常显示中文标签
 5 plt.rcParams['font.sans-serif'] = ['SimHei'] 
 6 # 用来正常显示负号
 7 plt.rcParams['axes.unicode_minus'] = False  
 8 X = df.排名
 9 Y = df.评分
10 
11 #评分与排名关系图
12 matplotlib.rcParams['font.sans-serif']=['SimHei']
13 plt.plot(x,y)
14 plt.xlabel("排名")
15 plt.ylabel("评分")
16 plt.title('评分与排名关系图')
17 plt.show()
18 #评分与排名柱状关系图
19 plt.bar(df.排名,df.评分)
20 
21 plt.xlabel("排名")
22 plt.ylabel("评分")
23 plt.title('评分与排名柱状关系图')
24 plt.show()

 

 

 

 

 1 #绘制折线图
 2 plt.rcParams['font.sans-serif']=['SimHei']
 3 a = df.排名
 4 b = df.评分
 5 plt.plot(a,b, color='b',label='评分')
 6 plt.xlabel("排名")
 7 plt.ylabel("评分")
 8 plt.title('排名与评分数据折线图')
 9 plt.legend(loc=1)
10 plt.grid()
11 plt.show()

 

 

 

 1 #绘制指数盒图
 2 import seaborn as sns
 3 def box():
 4     plt.title('评分指数盒图')
 5     a = df.排名
 6     b = df.评分
 7     sns.boxplot(a,b)
 8     plt.xlabel("排名")
 9     plt.ylabel("评分")
10 
11 box()

 

 

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变

量之间的回归方程(一元或多元)。

 1 #构建数据分析模型
 2 import numpy as np
 3 import pandas as pd
 4 import sklearn
 5 from sklearn import datasets
 6 from sklearn.linear_model import LinearRegression
 7 X = df[["排名"]]
 8 predict_model = LinearRegression()
 9 predict_model.fit(X, df[['评分']])
10 
11 print("回归系数为{}".format(predict_model.coef_))
12 print("回归方程截距:{}".format(predict_model.intercept_))

 

 

 1 #选择排名和评分两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
 2 colnames=[" ","排名","名称","评分"]
 3 df = pd.read_excel('C:/Users/方瑞行/3DM热门单机游戏排行榜.xlsx')
 4 # 用来正常显示中文标签
 5 plt.rcParams['font.sans-serif'] = ['SimHei'] 
 6 # 用来正常显示负号
 7 plt.rcParams['axes.unicode_minus'] = False  
 8 X = df.排名
 9 Y = df.评分
10 
11 #绘制散点图
12 def A():
13     plt.scatter(X,Y,color="blue",linewidth=2,label='评分')
14     plt.legend(loc=1)
15     plt.title("散点图",color="blue")
16     plt.grid()
17     plt.xlabel("排名")
18     plt.ylabel("评分")
19     plt.show()
20     
21 
22 def B():
23     plt.scatter(X,Y,color="green",linewidth=2)
24     plt.title("redu",color="blue")
25     plt.grid()
26     plt.show()
27     
28     
29 def func(p,x):
30     a,b,c=p
31     return a*x*x+b*x+c
32 
33 def error(p,x,y):
34     return func(p,x)-y
35 
36 def main():
37     plt.figure(figsize=(10,6))
38     p0=[0,0,0]
39     Para = leastsq(error,p0,args=(X,Y))
40     a,b,c=Para[0]
41     print("a=",a,"b=",b,"c=",c)
42     plt.scatter(X,Y,color="blue",linewidth=2,label='评分分布')
43     plt.legend(loc=1)
44     x=np.linspace(0,20,20)
45     y=a*x*x+b*x+c
46     plt.plot(x,y,color="red",linewidth=2,label="拟合曲线")
47     plt.legend(loc=1)
48     plt.title("一元二次方程关系图")
49     plt.xlabel("排名")
50     plt.ylabel("评分")
51     plt.grid()
52     plt.show()
53     
54 print(A())
55 
56 print(B())
57 
58 print(main())

 

 

 

 

 

6.数据持久化

1 #数据持久化
2 #将数据存入excel表
3 rank = r'3DM热门单机游戏排行榜.xlsx'
4 df.to_excel(rank)

 

 

7.将以上各部分的代码汇总,附上完整程序代码

  1  #导入相关库
  2  import requests
  3  #引入pandas用于数据可视化
  4  import pandas as pd
  5  import numpy as np
  6  import matplotlib.pyplot as plt
  7  import matplotlib
  8  import csv
  9  import scipy as sp
 10  import seaborn as sns
 11  from sklearn.linear_model import LinearRegression
 12  from bs4 import BeautifulSoup
 13  from pandas import DataFrame
 14  from scipy.optimize import leastsq
 15  import requests
 16  from bs4 import BeautifulSoup
 17  #3DM热门单机游戏排行榜
 18  r = requests.get("https://www.3dmgame.com/phb.html")
 19  r.encoding = "utf-8"    #为了简化代码,没有考虑异常情况。
 20  soup = BeautifulSoup(r.text,'html.parser')    #soup就是一个BeautifulSoup对象。
 21  #type(soup)
 22  print(soup.prettify())#基于bs4库HTML的格式输出,让页面更友好的显示
 23   #爬取数据
 24   #爬取游戏名
 25   h=[]
 26   for n in soup.find_all("a",class_="")[33:63]:
 27       h.append(n.get_text().strip())
 28           
 29   h
 30   
 31   #爬取排名
 32  c=[]
 33  for n in soup.find_all(class_="num"):
 34      c.append(n.get_text().strip())        
 35  
 36  c
 37  
 38  #爬取评分
 39  b=[]
 40  for i in soup.find_all('span', class_='')[8:-7:2]:
 41      b.append(i.get_text().strip())
 42  
 43  b
 44  
 45  #爬取游戏类型
 46  d=[]
 47  for i in soup.find_all('li', class_='')[12:-3:7]:
 48      d.append(i.get_text().strip())
 49  
 50  e=d
 51  e
 52   #将数据整理成表格
 53   print('{:^55}'.format('3DM热门单机游戏排行榜'))
 54   print('{:^5}\t{:^40}\t{:^30}\t{:^10}'.format('排名', '游戏名', '游戏类型', '评分'))
 55   num = 20
 56   lst = []
 57   for i in range(num):
 58       print('{:^5}\t{:^40}\t{:^30}\t{:^10}'.format(c[i], h[i], e[i],b[i]))
 59       lst.append([c[i],h[i], d[i],b[i]])
 60   df = pd.DataFrame(lst,columns=['排名', '游戏名', '游戏类型', '评分'])
 61  
 62  #将数据存入excel表
 63  rank = r'3DM热门单机游戏排行榜.xlsx'
 64  df.to_excel(rank)
 65  #数据清洗
 66  
 67   #重复值处理
 68   print(df.duplicated())
 69   
 70   #统计空值
 71   print(df.isnull().sum())  #返回0则没有空值
 72   
 73   #缺失值处理
 74  print(df[df.isnull().values==True]) #返回无缺失值
 75  
 76  #用describe()命令显示描述性统计指标
 77  print(df.describe())
 78  #选择排名和评分两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
 79   colnames=[" ","排名","名称","评分"]
 80   df = pd.read_excel('C:/Users/方瑞行/3DM热门单机游戏排行榜.xlsx')
 81   # 用来正常显示中文标签
 82   plt.rcParams['font.sans-serif'] = ['SimHei'] 
 83   # 用来正常显示负号
 84   plt.rcParams['axes.unicode_minus'] = False  
 85   X = df.排名
 86   Y = df.评分
 87  
 88  #评分与排名关系图
 89  matplotlib.rcParams['font.sans-serif']=['SimHei']
 90  plt.plot(x,y)
 91  plt.xlabel("排名")
 92  plt.ylabel("评分")
 93  plt.title('评分与排名关系图')
 94  plt.show()
 95  #评分与排名柱状关系图
 96  plt.bar(df.排名,df.评分)
 97  
 98  plt.xlabel("排名")
 99  plt.ylabel("评分")
100  plt.title('评分与排名柱状关系图')
101  plt.show()
102 #绘制折线图
103 plt.rcParams['font.sans-serif']=['SimHei']
104 a = df.排名
105 b = df.评分
106 plt.plot(a,b, color='b',label='评分')
107 plt.xlabel("排名")
108 plt.ylabel("评分")
109 plt.title('排名与评分数据折线图')
110 plt.legend(loc=1)
111 plt.grid()
112 plt.show()
113   #绘制指数盒图
114   import seaborn as sns
115   def box():
116       plt.title('评分指数盒图')
117       a = df.排名
118       b = df.评分
119       sns.boxplot(a,b)
120       plt.xlabel("排名")
121       plt.ylabel("评分")
122  
123  box()
124  #构建数据分析模型
125   import numpy as np
126   import pandas as pd
127   import sklearn
128   from sklearn import datasets
129   from sklearn.linear_model import LinearRegression
130   X = df[["排名"]]
131   predict_model = LinearRegression()
132   predict_model.fit(X, df[['评分']])
133  
134  print("回归系数为{}".format(predict_model.coef_))
135  print("回归方程截距:{}".format(predict_model.intercept_))
136  #选择排名和评分两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
137   colnames=[" ","排名","名称","评分"]
138   df = pd.read_excel('C:/Users/方瑞行/3DM热门单机游戏排行榜.xlsx')
139   # 用来正常显示中文标签
140   plt.rcParams['font.sans-serif'] = ['SimHei'] 
141   # 用来正常显示负号
142   plt.rcParams['axes.unicode_minus'] = False  
143   X = df.排名
144   Y = df.评分
145  
146  #绘制散点图
147  def A():
148      plt.scatter(X,Y,color="blue",linewidth=2,label='评分')
149      plt.legend(loc=1)
150      plt.title("散点图",color="blue")
151      plt.grid()
152      plt.xlabel("排名")
153      plt.ylabel("评分")
154      plt.show()
155      
156  
157  def B():
158      plt.scatter(X,Y,color="green",linewidth=2)
159      plt.title("redu",color="blue")
160      plt.grid()
161      plt.show()
162      
163      
164  def func(p,x):
165      a,b,c=p
166      return a*x*x+b*x+c
167  
168  def error(p,x,y):
169      return func(p,x)-y
170  
171  def main():
172      plt.figure(figsize=(10,6))
173      p0=[0,0,0]
174      Para = leastsq(error,p0,args=(X,Y))
175      a,b,c=Para[0]
176      print("a=",a,"b=",b,"c=",c)
177      plt.scatter(X,Y,color="blue",linewidth=2,label='评分分布')
178      plt.legend(loc=1)
179      x=np.linspace(0,20,20)
180      y=a*x*x+b*x+c
181      plt.plot(x,y,color="red",linewidth=2,label="拟合曲线")
182      plt.legend(loc=1)
183      plt.title("一元二次方程关系图")
184      plt.xlabel("排名")
185      plt.ylabel("评分")
186      plt.grid()
187      plt.show()
188      
189      print(A())
190 
191      print(B())
192  
193      print(main())
194 
195  #数据持久化
196  #将数据存入excel表
197  rank = r'3DM热门单机游戏排行榜.xlsx'
198  df.to_excel(rank)

 

 

(五)、总结(10 分)

1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?

根据数据分析可以发现,排名会随着评分的降低而降低,消费者可以按排名来选择游戏

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

在设计过程中,我收获到了如何编写爬虫程序,如何把网页想要爬取的内容提取出来,怎么画出自己想要的图像。改进的地方可能是编写代码经验不足吧,写代码的时候比较吃力。希望我自己在以后的就业或者提升中花费多些时间、精力来提升这一短板

 

posted @ 2021-12-28 23:08  夏•福  阅读(582)  评论(0编辑  收藏  举报