一、选题的背景 为什么要选择此选题?要达到的数据分析的预期目标是什么?(10 分) 从社会、经济、技术、数据来源等方面进行描述(200 字以内)
通过爬取数据后数据分析能够直观的看到二手车市场中某一品牌的相对数据,能够了解到现在的二手车市场情况,通过分析数据看到二手车的走势,车商就可以利用这些数据进行定价,让想买二手车却不了解市场的人了解到大概的价格走势,到了店里不会被骗。
二、主题式网络爬虫设计方案(10 分)
1.主题式网络爬虫名称
基于BeautifulSoup的二手车信息爬取和分析
2.主题式网络爬虫爬取的内容与数据特征分析
利用requests和BeautifulSoup爬取瓜子二手车网信息,爬取内容包括二手车的型号、价格、车龄、里程,然后清洗数据后获得自己想要的数据信息。其数据特征表现为:经过数据清洗后获得的数据没有重复值和无效值,让数据更具有说服力。
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
实现思路:绕过反爬获取网页资源,使用etree解析网页,用xpath定位爬取内容标签后爬取资源并将数据保存到csv文件中。
技术难点:设置请求头,for循环实现重复爬取
三、主题页面的结构特征分析(10 分)
1.主题页面的结构与特征分析
链接如下:https://www.guazi.com/fz/audi/
2.Htmls 页面解析
3.节点(标签)查找方法与遍历方法 (必要时画出节点树结构)
查找方法:find_all
遍历方法:for循环遍历
四、网络爬虫程序设计(60 分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后 面提供输出结果的截图。
- 数据爬取与采集
1 #导入库 2 import requests 3 from lxml import etree 4 import time 5 import re 6 import pandas as pd 7 8 #初始化空列表 9 carname_lis,carage_lis, price_lis, mileage_lis = [], [], [], [] 10 11 12 for a in range(10): 13 #爬取网站的网址并且循环爬取前10页的内容 14 url = "https://www.guazi.com/fz/audi/{}/#bread".format(a*10) 15 16 #设置请求头 17 headers = { 18 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" 19 } 20 #requests请求链接 21 resp = requests.get(url,headers=headers).text 22 23 #使用lxml模块中的etree方法讲字符串转化为html标签 24 html = etree.HTML(resp) 25 26 #用xpath定位标签位置 27 lis = html.xpath("/html/body/div[6]/ul/li") 28 29 #获取要爬取内容的详情链接 30 for li in lis: 31 #爬取车名 32 carname = li.xpath("./a/h2/text()")[0] 33 #爬取车龄 34 carage = li.xpath("./a/div[1]/text()")[0] 35 #爬取里程 36 milrage = li.xpath("./a/div[1]/text()[2]")[0] 37 #爬取价格 38 price = li.xpath("./a/div[2]/p/text()")[0] 39 40 #输出 41 print(carname) 42 print(carage) 43 print(milrage) 44 print(price) 45 # 将字段存入初始化的列表中 46 carname_lis.append(carname) 47 carage_lis.append(carage) 48 mileage_lis.append(milrage) 49 price_lis.append(price) 50 51 #pandas中的模块将数据存入 52 df = pd.DataFrame({ 53 "型号" : carname_lis, 54 "车龄" : carage_lis, 55 "里程" : mileage_lis, 56 "价格" : price_lis, 57 }) 58 #储存为csv文件 59 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)
2.对数据进行清洗和处理
1 #导入库 2 import pandas as pd 3 import numpy as mp 4 import sklearn 5 import seaborn as sns 6 import matplotlib.pyplot as plt 7 #读取csv文件 8 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 9 aodi.head()
1 #检查重复值 2 aodi.duplicated()
1 #删除重复值 2 aodi = aodi.drop_duplicates() 3 aodi.head()
1 #清洗文字左右空格 2 aodi['型号'] = aodi['型号'].map(str.strip) 3 aodi['车龄'] = aodi['车龄'].map(str.strip) 4 aodi['里程'] = aodi['里程'].map(str.strip) 5 aodi.head()
3.文本分析(可选):jieba 分词、wordcloud 的分词可视化
4.数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)
1 #价格直方图 2 sns.distplot(aodi['价格'])
1 #车龄占比饼图 2 plt.rcParams['font.sans-serif'] = ['SimHei']#解决乱码问题 3 df_score = aodi['车龄'].value_counts() #统计评分情况 4 plt.title("车龄占比图") #设置饼图标题 5 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #绘图 6 #autopct表示圆里面的文本格式,在python里%操作符可用于格式化字符串操作 7 plt.show()
5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变 量之间的回归方程(一元或多元)。
1 #绘制散点图查看关系 2 sns.regplot(x = '价格',y = '车龄',data=aodi)
1 import pandas as pd 2 import numpy as mp 3 import sklearn 4 import seaborn as sns 5 import matplotlib.pyplot as plt 6 from scipy.optimize import leastsq 7 plt.rcParams['font.sans-serif'] = ['SimHei']#解决乱码问题 8 #读取文件 9 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 10 #定义变量 11 price=aodi.loc[:,'价格'] 12 year=aodi.loc[:,'年'] 13 #函数表达式 14 def func(params,x): 15 a,b,c=params 16 return a*x*x+b*x+c 17 def error_func(params,x,y): 18 return func(params,x)-y 19 P0=[1,9.0] 20 def main(): 21 plt.figure(figsize=(8,6)) 22 P0=[1,9.0,1] 23 Para=leastsq(error_func,P0,args=(price,year)) 24 a,b,c=Para[0] 25 print("a=",a, "b=",b, "c=",c) 26 #绘图 27 plt.scatter(price,year,color="green",label="样本数据",linewidth=2) 28 x=mp.linspace(1,50,40) 29 y=a*x*x+b*x+c 30 #右上角标 31 plt.plot(x,y,color="red",label="拟合曲线",linewidth=2) 32 #x,y轴名称 33 plt.xlabel('价格') 34 plt.ylabel('车龄') 35 #标题 36 plt.title("价格与车龄回归方程") 37 plt.grid() 38 plt.legend() 39 plt.show() 40 main()
6.数据持久化
1 #储存为csv 2 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)
7.将以上各部分的代码汇总,附上完整程序代码
1 #导入库 2 import requests 3 from lxml import etree 4 import time 5 import re 6 import pandas as pd 7 8 #初始化空列表 9 carname_lis,carage_lis, price_lis, mileage_lis = [], [], [], [] 10 11 12 for a in range(10): 13 #爬取网站的网址并且循环爬取前10页的内容 14 url = "https://www.guazi.com/fz/audi/{}/#bread".format(a*10) 15 16 #设置请求头 17 headers = { 18 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" 19 } 20 #requests请求链接 21 resp = requests.get(url,headers=headers).text 22 23 #使用lxml模块中的etree方法讲字符串转化为html标签 24 html = etree.HTML(resp) 25 26 #用xpath定位标签位置 27 lis = html.xpath("/html/body/div[6]/ul/li") 28 29 #获取要爬取内容的详情链接 30 for li in lis: 31 #爬取车名 32 carname = li.xpath("./a/h2/text()")[0] 33 #爬取车龄 34 carage = li.xpath("./a/div[1]/text()")[0] 35 #爬取里程 36 milrage = li.xpath("./a/div[1]/text()[2]")[0] 37 #爬取价格 38 price = li.xpath("./a/div[2]/p/text()")[0] 39 40 #输出 41 print(carname) 42 print(carage) 43 print(milrage) 44 print(price) 45 # 将字段存入初始化的列表中 46 carname_lis.append(carname) 47 carage_lis.append(carage) 48 mileage_lis.append(milrage) 49 price_lis.append(price) 50 51 #pandas中的模块将数据存入 52 df = pd.DataFrame({ 53 "型号" : carname_lis, 54 "车龄" : carage_lis, 55 "里程" : mileage_lis, 56 "价格" : price_lis, 57 }) 58 #储存为csv文件 59 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False) 60 61 #导入库 62 import pandas as pd 63 import numpy as mp 64 import sklearn 65 import seaborn as sns 66 import matplotlib.pyplot as plt 67 #读取csv文件 68 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 69 aodi.head() 70 #检查重复值 71 aodi.duplicated() 72 #删除重复值 73 aodi = aodi.drop_duplicates() 74 aodi.head() 75 76 #清洗文字左右空格 77 aodi['型号'] = aodi['型号'].map(str.strip) 78 aodi['车龄'] = aodi['车龄'].map(str.strip) 79 aodi['里程'] = aodi['里程'].map(str.strip) 80 aodi.head() 81 82 #价格直方图 83 sns.distplot(aodi['价格']) 84 85 86 #车龄占比饼图 87 plt.rcParams['font.sans-serif'] = ['SimHei']#解决乱码问题 88 df_score = aodi['车龄'].value_counts() #统计评分情况 89 plt.title("车龄占比图") #设置饼图标题 90 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #绘图 91 #autopct表示圆里面的文本格式,在python里%操作符可用于格式化字符串操作 92 plt.show() 93 94 #绘制散点图查看关系 95 sns.regplot(x = '价格',y = '车龄',data=aodi) 96 97 #储存为csv文件 98 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)
五、总结(10 分)
1.经过对主题数据的分析与可视化,可以得到哪些结论?
(1)14、19、16这三个年份的二手车比较多,老车反而比较少
(2)价格较高的车都是19、20、21这三个年份的
(3)可视化的数据相当直观,一眼就能找到需要的
2.在完成此设计过程中,得到哪些收获?以及要改进的建议?
在这次的设计过程中,很多东西都是自己一步一步摸索的,因为有些代码就算一样复制过来也用不了,虽然这次没有完全实现,也还存在一些问题,在解决一个又一个问题之后,我自己也对python这门语言有了更深的理解,也越发觉得有趣。希望自己下次在绘图上可以做的更好。