网络爬虫——爬取手机厚度排行

一、选题的背景

手机这个产品本身就不是标准,所以终究会出现各种厚度不一的产品,而厚度又成为了手机产品中一个及其重要的参数,就是这个参数,各种厂家为了降低他绞尽脑汁。首先从营销来看,从定位角度上来看,手机比人薄小数点后两位可能就是一个抢占用户第一心智的关键点,在信息如此爆炸的现在,一个心智的第一是无比重要的。利用爬虫工具爬取手机厚度排行数据,然后进行分析的结果可视化输出。

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

1.主题式网络爬虫名称:爬取手机厚度排行

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

爬取手机厚度排名,选取排名、名字、厚度这三个方面进行数据分析

3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

实现思路:导入需要用到的库,获取界面,数据分析,将数据保存至csv文件里,然后根据爬取到的数据可视化分析。

技术难点:查找相关库并导入

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

爬取网站:手机厚度排行榜 - 快科技天梯榜 (kkj.cn)

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

 

 2.Htmls页面解析

 

 

 

四、网络爬虫程序设计

1.数据爬取与采集

 1 #-*- coding = utf-8 -*-
 2 from bs4 import BeautifulSoup
 3 #进行网页解析
 4 
 5 import re
 6 #进行文字匹配
 7 
 8 import urllib.request,urllib.error
 9 #制定URL,获取网页数据
10 
11 import xlwt
12 #进行excel操作
13 
14 import sqlite3
15 #进行SQLite数据库操作
16 
17 
18 def getData(url):
19     datalist = []
20     html = askURL(url)
21     soup = BeautifulSoup(html,"html.parser")
22     i=1
23     for item in soup.find_all('tr', class_="list_tr"):
24         data = []
25         item = str(item)
26         
27         pm = i
28         i=i+1
29         data.append(pm)
30         
31         findbt = re.compile(r'href="javascript:;".*>(.*?)</a>')
32         bt = re.findall(findbt, item)[0]
33         data.append(bt)
34         findrs = re.compile(r'class="mark1">(.*?)</li>')
35         rs = re.findall(findrs, item)[0].replace("mm","")
36         data.append(rs)
37         datalist.append(data) 
38         if i==31:
39             break   
40     return datalist
41 
42 
43 def askURL(url):
44     head = {
45         "User-Agent": "Mozilla / 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome / 96.0.4664.110 Safari / 537.36"
46     }
47     request = urllib.request.Request(url, headers=head)
48     html = ""
49     try:
50         response = urllib.request.urlopen(request)
51         html = response.read().decode("utf-8")
52     except urllib.error.URLError as e:
53         if hasattr(e, "code"):
54             print(e.code)
55 
56         if hasattr(e, "reason"):
57             print(e.reason)
58         
59     return html
60 
61 url = "https://rank.kkj.cn/Phone63.shtml"
62 getData(url)
63 print("爬取完毕!")
64 
65 
66 
67 url = ("https://rank.kkj.cn/Phone63.shtml")
68 html=askURL(url)
69 datalist = getData(url)
70 print(datalist)
71 print("爬取完毕!")
72 savepath = ".\\手机厚度排行榜.xls"
73 book = xlwt.Workbook(encoding="utf-8",style_compression=0)
74     #创建workbook对象
75 sheet = book.add_sheet('手机厚度排行榜',cell_overwrite_ok=True)
76 
77     #创建工作表
78 col = ("排名","手机名称","手机厚度")
79 
80 for i in range(0,3):
81     sheet.write(0,i,col[i]) #列名
82 
83 for i in range(0,30):
84 
85         #测试 print("第%d条" %(i+1))
86 
87     data = datalist[i]
88     for j in range(0,3):
89         sheet.write(i+1,j,data[j])
90             #数据
91 
92 book.save(savepath)
93 
94 print('已输出表格!')

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

导入数据

1 #导入数据
2 import pandas as pd
3 import numpy as np
4 import seaborn as sns
5 import sklearn
6 #导入数据
7 ranking=pd.DataFrame(pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls'))
8 #显示数据前五行
9 ranking.head()

查找重复值

 

 1 #查找重复值 2 ranking.duplicated() 

删除重复值

1 #删除重复值
2 ranking=ranking.drop_duplicates()
3 #输出数据前五行
4 ranking.head()

 

 

异常值查询

 1 #异常值查询 2 ranking.describe() 

3.文本分析(可选):jieba分词,wordcloud可视化

4.数据分析与可视化

#柱状图
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df=pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls')
index=np.array(df['排名'])
#索引
data=np.array(df['手机厚度'])
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['Arial Unicode MS']
#用来正常显示负号
plt.rcParams['axes.unicode_minus']=False 
#修改x轴字体大小为12
plt.xticks(fontsize=12)
#修改y轴字体大小为12
plt.yticks(fontsize=12)  
print(data)
print(index)
#x标签 
plt.xlabel('排名')
#y标签
plt.ylabel('手机厚度')
s = pd.Series(data, index)
s.plot(kind='bar',color='g')
plt.grid()
plt.show()

 

 

 1 #散点图、折线图
 2 kuake_df=pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls')
 3 plt.rcParams['font.sans-serif']=['Arial Unicode MS'] 
 4 plt.rcParams['axes.unicode_minus']=False 
 5 plt.xticks(fontsize=12)  
 6 plt.yticks(fontsize=12)
 7 #散点
 8 plt.scatter(kuake_df.排名, kuake_df.手机厚度,color='b')
 9 #折线
10 plt.plot(kuake_df.排名, kuake_df.手机厚度,color='r')
11 #x标签 
12 plt.xlabel('排名')
13 #y标签
14 plt.ylabel('手机厚度')
15 plt.show()

 1 # 扇形图 条形图
 2 import matplotlib.pyplot as plt
 3 plt.rcParams['font.sans-serif']=['SimHei'] #显示中文
 4 plt.rcParams['axes.unicode_minus']=False
 5 Type = ['6.50~7.00', '7.00~7.50', '7.50~8.00']
 6 Data = [3, 16,11]
 7 plt.pie(Data ,labels=Type, autopct='%1.1f%%')
 8 plt.axis('equal')
 9 plt.title('手机厚度区间所占比例')
10 plt.show()
11 plt.bar(['6.50~7.00', '7.00~7.50', '7.50~8.00'],
12         [3, 16,11],
13         label="手机厚度区间所占比例")
14 plt.legend()
15 plt.show()

 

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程(一元或多元)

 1 import scipy.optimize as opt
 2 import matplotlib.pyplot as plt
 3 import matplotlib
 4 x0=np.array(df['排名'])
 5 y0=np.array(df['手机厚度'])
 6 def func(x,c0):
 7     a,b,c=c0
 8     return a*x**2+b*x+c
 9 def errfc(c0,x,y):
10     return y-func(x,c0)
11 c0=[0,2,3]
12 c1=opt.leastsq(errfc,c0,args=(x0,y0))[0]
13 a,b,c=c1
14 print(f"拟合方程为:y={a}*x**2+{b}*x+{c}")
15 chinese=matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')
16 plt.plot(x0,y0,"ob",label="样本数据")
17 plt.plot(x0,func(x0,c1),"r",label="拟合曲线")
18 #x标签
19 plt.xlabel("排名")
20 #y标签
21 plt.ylabel("手机厚度")
22 plt.legend(loc=3,prop=chinese)
23 plt.show()

 

6.数据持久化

保存数据,方便下次使用。

7.汇总

  1 #-*- coding = utf-8 -*-
  2 from bs4 import BeautifulSoup
  3 #进行网页解析
  4 
  5 import re
  6 #进行文字匹配
  7 
  8 import urllib.request,urllib.error
  9 #制定URL,获取网页数据
 10 
 11 import xlwt
 12 #进行excel操作
 13 
 14 import sqlite3
 15 #进行SQLite数据库操作
 16 
 17 
 18 def getData(url):
 19     datalist = []
 20     html = askURL(url)
 21     soup = BeautifulSoup(html,"html.parser")
 22     i=1
 23     for item in soup.find_all('tr', class_="list_tr"):
 24         data = []
 25         item = str(item)
 26         
 27         pm = i
 28         i=i+1
 29         data.append(pm)
 30         
 31         findbt = re.compile(r'href="javascript:;".*>(.*?)</a>')
 32         bt = re.findall(findbt, item)[0]
 33         data.append(bt)
 34         findrs = re.compile(r'class="mark1">(.*?)</li>')
 35         rs = re.findall(findrs, item)[0].replace("mm","")
 36         data.append(rs)
 37         datalist.append(data) 
 38         if i==31:
 39             break   
 40     return datalist
 41 
 42 
 43 def askURL(url):
 44     head = {
 45         "User-Agent": "Mozilla / 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome / 96.0.4664.110 Safari / 537.36"
 46     }
 47     request = urllib.request.Request(url, headers=head)
 48     html = ""
 49     try:
 50         response = urllib.request.urlopen(request)
 51         html = response.read().decode("utf-8")
 52     except urllib.error.URLError as e:
 53         if hasattr(e, "code"):
 54             print(e.code)
 55 
 56         if hasattr(e, "reason"):
 57             print(e.reason)
 58         
 59     return html
 60 
 61 url = "https://rank.kkj.cn/Phone63.shtml"
 62 getData(url)
 63 print("爬取完毕!")
 64 
 65 
 66 
 67 url = ("https://rank.kkj.cn/Phone63.shtml")
 68 html=askURL(url)
 69 datalist = getData(url)
 70 print(datalist)
 71 print("爬取完毕!")
 72 savepath = ".\\手机厚度排行榜.xls"
 73 book = xlwt.Workbook(encoding="utf-8",style_compression=0)
 74     #创建workbook对象
 75 sheet = book.add_sheet('手机厚度排行榜',cell_overwrite_ok=True)
 76 
 77     #创建工作表
 78 col = ("排名","手机名称","手机厚度")
 79 
 80 for i in range(0,3):
 81     sheet.write(0,i,col[i]) #列名
 82 
 83 for i in range(0,30):
 84 
 85         #测试 print("第%d条" %(i+1))
 86 
 87     data = datalist[i]
 88     for j in range(0,3):
 89         sheet.write(i+1,j,data[j])
 90             #数据
 91 
 92 book.save(savepath)
 93 
 94 print('已输出表格!')
 95 
 96 #数据清洗
 97 import pandas as pd
 98 import numpy as np
 99 import seaborn as sns
100 import sklearn
101 #导入数据
102 ranking=pd.DataFrame(pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls'))
103 #显示数据前五行
104 ranking.head()
105 
106 #查找重复值
107 ranking.duplicated()
108 
109 #删除重复值
110 ranking=ranking.drop_duplicates()
111 #输出数据前五行
112 ranking.head()
113 
114 #异常值查询
115 ranking.describe()
116 
117 #柱状图
118 import matplotlib.pyplot as plt
119 import pandas as pd
120 import numpy as np
121 df=pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls')
122 index=np.array(df['排名'])
123 #索引
124 data=np.array(df['手机厚度'])
125 #用来正常显示中文标签
126 plt.rcParams['font.sans-serif']=['Arial Unicode MS']
127 #用来正常显示负号
128 plt.rcParams['axes.unicode_minus']=False 
129 #修改x轴字体大小为12
130 plt.xticks(fontsize=12)
131 #修改y轴字体大小为12
132 plt.yticks(fontsize=12)  
133 print(data)
134 print(index)
135 #x标签 
136 plt.xlabel('排名')
137 #y标签
138 plt.ylabel('手机厚度')
139 s = pd.Series(data, index)
140 s.plot(kind='bar',color='g')
141 plt.grid()
142 plt.show()
143 
144 #散点图、折线图
145 kuake_df=pd.read_excel(r'C:\Users\liuquanwang\Desktop\手机厚度排行榜.xls')
146 plt.rcParams['font.sans-serif']=['Arial Unicode MS'] 
147 plt.rcParams['axes.unicode_minus']=False 
148 plt.xticks(fontsize=12)  
149 plt.yticks(fontsize=12)
150 #散点
151 plt.scatter(kuake_df.排名, kuake_df.手机厚度,color='b')
152 #折线
153 plt.plot(kuake_df.排名, kuake_df.手机厚度,color='r')
154 #x标签 
155 plt.xlabel('排名')
156 #y标签
157 plt.ylabel('手机厚度')
158 plt.show()
159 
160 # 扇形图 条形图
161 import matplotlib.pyplot as plt
162 plt.rcParams['font.sans-serif']=['SimHei'] #显示中文
163 plt.rcParams['axes.unicode_minus']=False
164 Type = ['6.50~7.00', '7.00~7.50', '7.50~8.00']
165 Data = [3, 16,11]
166 plt.pie(Data ,labels=Type, autopct='%1.1f%%')
167 plt.axis('equal')
168 plt.title('手机厚度区间所占比例')
169 plt.show()
170 plt.bar(['6.50~7.00', '7.00~7.50', '7.50~8.00'],
171         [3, 16,11],
172         label="手机厚度区间所占比例")
173 plt.legend()
174 plt.show()
175 
176 #建立直线回归方程
177 import scipy.optimize as opt
178 import matplotlib.pyplot as plt
179 import matplotlib
180 x0=np.array(df['排名'])
181 y0=np.array(df['手机厚度'])
182 def func(x,c0):
183     a,b,c=c0
184     return a*x**2+b*x+c
185 def errfc(c0,x,y):
186     return y-func(x,c0)
187 c0=[0,2,3]
188 c1=opt.leastsq(errfc,c0,args=(x0,y0))[0]
189 a,b,c=c1
190 print(f"拟合方程为:y={a}*x**2+{b}*x+{c}")
191 chinese=matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')
192 plt.plot(x0,y0,"ob",label="样本数据")
193 plt.plot(x0,func(x0,c1),"r",label="拟合曲线")
194 #x标签
195 plt.xlabel("排名")
196 #y标签
197 plt.ylabel("手机厚度")
198 plt.legend(loc=3,prop=chinese)
199 plt.show()

五、总结

通过对数据分析可知现在的手机越来越追求手机的薄,但普遍手机厚度在7.50mm左右,说明厂家在追求手机薄厚的同时也更关注手机的质量。

将本学期的知识更加融会贯通,但也暴露了一些缺点,数据的可视化不够熟练,在写代码的时候还需查找书籍和资料。

 

posted @ 2021-12-31 03:08  刘权旺  阅读(98)  评论(0编辑  收藏  举报