网络爬虫——爬取手机厚度排行
作者:互联网
一、选题的背景
手机这个产品本身就不是标准,所以终究会出现各种厚度不一的产品,而厚度又成为了手机产品中一个及其重要的参数,就是这个参数,各种厂家为了降低他绞尽脑汁。首先从营销来看,从定位角度上来看,手机比人薄小数点后两位可能就是一个抢占用户第一心智的关键点,在信息如此爆炸的现在,一个心智的第一是无比重要的。利用爬虫工具爬取手机厚度排行数据,然后进行分析的结果可视化输出。
二、主题式网络爬虫设计方案
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左右,说明厂家在追求手机薄厚的同时也更关注手机的质量。
将本学期的知识更加融会贯通,但也暴露了一些缺点,数据的可视化不够熟练,在写代码的时候还需查找书籍和资料。
标签:plt,厚度,爬虫,爬取,print,手机,排行,import,data 来源: https://www.cnblogs.com/2818151164qq/p/15737948.html