Python高级应用程序设计任务要求
用Python实现一个面向主题的网络爬虫程序,并完成以下内容:
(注:每人一题,主题内容自选,所有设计内容与源代码需提交到博客园平台)
一、主题式网络爬虫设计方案(15分)
1.主题式网络爬虫名称
1.1毒APP平台品牌鞋的爬取
2.主题式网络爬虫爬取的内容与数据特征分析
2.1爬虫的内容
鞋子价格,鞋号,描述信息,颜色,货号,发售日期
2.2 数据特征分析
2.2.1对title,sellDate和authPrice做一个透视表并可视化
2.2.2对articleNumber,sellDate和authPrice做一个透视表并可视化
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
3.1实现思路
创建一个DuApp的类,定义_init_()方法用来处理每一的请求,recensales_list_url()方法用来构建最近购买记录,brand_list_url()方法构建商品品类列列表,product _detail_url()方法构建商品详情,getTime获取具体时间精确到分钟,text_save()方法保存数据到csv文件中,data_write将数据写入新文件,具体如下图解。
3.2技术难点
爬取过程中并未遇到阻拦,既不需要设置header, 也没遇到在爬取过程中被重定向到登录页面。
二、主题页面的结构特征分析(15分)
1.主题页面的结构特征
每页30项数据,共计181页,数据项10840,不存在应拖动滚动条而动态加载的数据项,即div,通过右键查看网页源代码分析需要提取的数据是否存在动态生成的数据,任意查看一个数据项中与原网页中的数据对比后,发现所需要爬取的数据都是静态的。
2.Htmls页面解析
框框中的数据都是需要爬取的字段。
3.节点(标签)查找方法与遍历方法
(必要时画出节点树结构)
查找节点的方法采用json的Selector选择器,用xpath来提取所需要的数据。从整体(list)到部分(product)的查找方式,即先确定爬取的数据所在哪个json的节点中,找到这个节点的所有直接子节点,也就是每一个攻略项,再用for循环依次遍历,然后再具体解析遍历的每一项攻略的数据,图解如下。
三、网络爬虫程序设计(60分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后面提供输出结果的截图。
1.数据爬取与采集
# !/usr/bin/env python # -*- encoding: utf-8 -*- import execjs import requests import json import re import time import datetime import arrow import os import xlwt import pymongo class DuApp(object): def __init__(self): # 数据库 self.conn = pymongo.MongoClient(host=‘127.0.0.1‘, port=27017) self.db = self.conn.Duapp # 选择集合 self.collection = self.db.DuappPro self.headers = { ‘Host‘: "app.poizon.com", ‘User-Agent‘: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)" " Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.4.501 NetType/WIFI " "MiniProgramEnv/Windows WindowsWechat", ‘appid‘: "wxapp", ‘appversion‘: "4.4.0", ‘content-type‘: "application/x-www-form-urlencoded", ‘Accept-Encoding‘: "gzip, deflate", ‘Accept‘: "*/*", } self.img_path = ‘image‘ def get_recensales_list_url(self, lastId, productId): """ 构建最近购买记录url :param lastId: 起始页 :param productId: 商品id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘lastId{}limit20productId{}sourceAppapp19bc545a393a25177083d4a748807cc0‘.format( lastId, productId)) recensales_list_url = ‘https://app.poizon.com/api/v1/h5/product/fire/recentSoldList?‘ ‘productId={}&lastId={}&limit=20&sourceApp=app&sign={}‘.format(productId, lastId, sign) return recensales_list_url def get_brand_list_url(self, lastId, tabId): """ 构建商品品类列表 :param lastId: 起始页 :param tabId: 分类id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘lastId{}limit20tabId{}19bc545a393a25177083d4a748807cc0‘.format(lastId, tabId)) brand_list_url = ‘https://app.poizon.com/api/v1/h5/index/fire/shoppingTab?‘ ‘tabId={}&limit=20&lastId={}&sign={}‘.format(tabId, lastId, sign) return brand_list_url def get_product_detail_url(self, productId): """ 构建商品详情url :param productId: 商品id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘productId{}productSourceNamewx19bc545a393a25177083d4a748807cc0‘.format(productId)) product_detail_url = ‘https://app.poizon.com/api/v1/h5/index/fire/flow/product/detail?‘ ‘productId={}&productSourceName=wx&sign={}‘.format(productId, sign) return product_detail_url def get_brand_list_data(self, brand_list_url): """ 商品分类列表 :param url: 商品分类列表url :return: """ response = requests.get(url=brand_list_url, headers=self.headers) return response def get_product_detail_data(self, product_detail_url): """ 商品详情 :param url: 商品详情地址 :return: """ response = requests.get(url=product_detail_url, headers=self.headers) return response def get_recensales_list_data(self, recensales_list_url): """ 商品地址 :param recensales_list_url: 商品地址 :return: """ response = requests.get(url=recensales_list_url, headers=self.headers) return response def get_recensales_list_data(self, recensales_list_url): """ 商品地址 :param recensales_list_url: 商品地址 :return: """ response = requests.get(url=recensales_list_url, headers=self.headers) return response def getTime(self, flag, dayhourminute): ‘‘‘ 获取几小时之前,几分钟前,几天前,几个月前,及几年前的具体时间 flag, 1:天;2:小时;3:分钟;4:月,5:年 :param flag: 1:天;2:小时;3:分钟;4:月,5:年 :param dayhourminute: 整数值 :return: 具体时间 %Y-%m-%d %H:%M:%S ‘‘‘ tn = datetime.datetime.now() t = None ttime = ‘‘ if flag <= 1: if flag == 1: t = datetime.timedelta(days=dayhourminute) elif flag == 2: t = datetime.timedelta(hours=dayhourminute) elif flag == 3: t = datetime.timedelta(minutes=dayhourminute) strtime = tn - t ttime = strtime.strftime(‘%Y-%m-%d‘) else: dt = arrow.now() if flag == 4: ttime = dt.shift(months=-dayhourminute).format("YYYY-MM-DD") elif flag == 5: ttime = str(int( datetime.datetime.now().strftime( "%Y")) - dayhourminute) + "-" + datetime.datetime.now().strftime( "%m-%d") return ttime def download(self, picDict): # list for pic in picDict: url = pic[‘logoUrl‘] time_str = str(round(time.time() * 1000)) # 当前时间戳 img_name = time_str + ‘.png‘ try: path = os.path.join(self.img_path, img_name) if not os.path.exists(path): r = requests.get(url) r.raise_for_status() # 使用with语句可以不用自己手动关闭已经打开的文件流 with open(path, "wb") as f: # 开始写文件,wb代表写二进制文件 f.write(r.content) print("下载完成") else: print("文件已存在") except Exception as e: print("下载失败:" + str(e)) def get_data(self): # 商品品类列表 # app里面为购买menu 搜索下面table 这里只看了球鞋 # tabId 4 为球鞋品类, lastId 1 为翻页参数 for i in range(1, 999): try: logoUrlList = [] product_mongo_data_list = [] brand_list_url = self.get_brand_list_url(i, 4) # 商品品类列表data response = self.get_brand_list_data(brand_list_url) contents = json.loads(response.content, encoding=‘UTF-8‘) lists = contents.get(‘data‘) lists = lists.get(‘list‘) for product in lists: productId = product.get(‘productId‘) # productId = 47209 # 测试使用 # 商品详情 product_detail_url = self.get_product_detail_url(productId) # 商品详情data response = self.get_product_detail_data(product_detail_url) product_contents = json.loads(response.content, encoding=‘UTF-8‘) # 解析商品信息 logoUrl = product_contents.get(‘data‘) logoUrl = logoUrl.get(‘detail‘) logoUrl = logoUrl.get(‘logoUrl‘) # 图片 --主图 picDict = {‘productId‘: productId, ‘logoUrl‘: logoUrl} logoUrlList.append(picDict) # 放入一个集合 title = product_contents.get(‘data‘) title = title.get(‘detail‘) title = title.get(‘title‘) # 标题 sellDate = product_contents.get(‘data‘) sellDate = sellDate.get(‘detail‘) sellDate = sellDate.get(‘sellDate‘) # 发售日期 articleNumber = product_contents.get(‘data‘) articleNumber = articleNumber.get(‘detail‘) articleNumber = articleNumber.get(‘articleNumber‘) # 编号 color = product_contents.get(‘data‘) color = color.get(‘detail‘) color = color.get(‘color‘) # 颜色说明 authPrice = product_contents.get(‘data‘) authPrice = authPrice.get(‘detail‘) authPrice = authPrice.get(‘authPrice‘) # 价格 imageAndText = product_contents.get(‘data‘) imageAndText = imageAndText.get(‘detail‘) imageAndText = imageAndText.get(‘imageAndText‘) # 详情页 product_mongo_data = {‘productId‘: productId, ‘logoUrl‘: logoUrl, ‘title‘: title, ‘sellDate‘: sellDate, ‘articleNumber‘: articleNumber, ‘color‘: color, ‘authPrice‘: authPrice, ‘imageAndText‘: imageAndText} print(product_mongo_data) product_mongo_data_list.append(product_mongo_data) #批量存储 self.collection = self.db.DuappPro self.collection.insert_many(product_mongo_data_list) except Exception as e: print(e) print("something error") # 没有数据或者遇到异常,结束 break def text_save(self, filename, data): # filename为写入CSV文件的路径,data为要写入数据列表. file = open(filename, ‘w+‘, encoding=‘utf-8‘) for i in range(len(data)): s = str(data[i]).replace(‘[‘, ‘‘).replace(‘]‘, ‘‘) # 去除[],这两行按数据不同,可以选择 s = s.replace("‘", ‘‘).replace(‘,‘, ‘‘) + ‘\n‘ # 去除单引号,逗号,每行末尾追加换行符 file.write(s) file.close() print("保存文件成功") # 将数据写入新文件 def data_write(self, file_path, datas): f = xlwt.Workbook() sheet1 = f.add_sheet(u‘sheet1‘, cell_overwrite_ok=True) # 创建sheet # 将数据写入第 i 行,第 j 列 i = 0 for data in datas: for j in range(len(data)): sheet1.write(i, j, data[j]) i = i + 1 f.save(file_path) # 保存文件 def text_save(self,filename, data): # filename为写入CSV文件的路径,data为要写入数据列表. file = open(filename, ‘w+‘,encoding=‘utf-8‘) for i in range(len(data)): s = str(data[i]).replace(‘[‘, ‘‘).replace(‘]‘, ‘‘) # 去除[],这两行按数据不同,可以选择 s = s.replace("‘", ‘‘).replace(‘,‘, ‘‘) + ‘\n‘ # 去除单引号,逗号,每行末尾追加换行符 file.write(s) file.close() print("保存文件成功") # 将数据写入新文件 def data_write(self,file_path, datas): f = xlwt.Workbook() sheet1 = f.add_sheet(u‘sheet1‘, cell_overwrite_ok=True) # 创建sheet # 将数据写入第 i 行,第 j 列 i = 0 for data in datas: for j in range(len(data)): sheet1.write(i, j, data[j]) i = i + 1 f.save(file_path) # 保存文件 if __name__ == ‘__main__‘: duapp = DuApp() duapp.get_data() # duapp.text_save(‘duapp.txt‘,product_mongo_data_list) # duapp.data_write(‘duapp.xlsx‘,product_mongo_data_list) # 下载图片 # duapp.download(logoUrlList)
具体截图如下:
2.对数据进行清洗和处理
2.1对数据进行加载,导入本地数据文件
import pandas as pd df =pd.DataFrame(pd.read_csv(‘C:/Users/Administrator/Desktop/DuappPro.csv‘)) df.head()
2.2删除无效的数据列
df.drop(‘logoUrl‘,axis=1,inplace=True) df.head()
df.drop(‘imageAndText‘,axis=1,inplace =True) df.head()
2.3对数据进行重复值处理
df.duplicated()
删除重复的数据值
df = df.drop_duplicates()
df.head()
数据的空值与缺失值处理
df[‘color‘].isnull().value_counts()
数据的异常值处理
df.describe()
通过观察发现authPrice中的最大值为8.999900e+06,而该列的数据平均值为1.076037e+05。所以觉得最大值可能为一个异常值,将其用平均值代替。
df.replace([8.999900e+06],df[‘authPrice‘].mean())
3.文本分析(可选):jieba分词、wordcloud可视化
4.数据分析与可视化
(例如:数据柱形图、直方图、散点图、盒图、分布图、数据回归分析等)
4.1 需求1:查看耐克品牌的价格走势
def matplotlibAns(self): # matplotlib中有很多可用的模块,我们使用pyplot模块 data = self.collection.find({‘title‘: {‘$regex‘: ‘耐克‘}}) year = [2010, 2012, 2014, 2016] price = [20, 40, 60, 100] for du in data: year.append(du[‘sellDate‘]) price.append(du[‘authPrice‘]) #生成图表 pyplot.plot(year, price) #设置横坐标为year,纵坐标为population,标题为Population year correspondence pyplot.xlabel(‘time‘) pyplot.ylabel(‘price‘) pyplot.title(‘price time correspondence‘) #设置纵坐标刻度 pyplot.yticks([0, 150000, 250000, 750000, 900000]) #设置填充选项:参数分别对应横坐标,纵坐标,纵坐标填充起始值,填充颜色(可以有更多选项) pyplot.fill_between(year, price, 10, color = ‘green‘) #显示图表 pyplot.show()
4.2 需求2: 查看Nike Rokit x Kyrie 5 Welcome Home "welcome Home" 全明星在各个年份的价格走势
def matplotlibAnsPro(self,productId): # matplotlib中有很多可用的模块,我们使用pyplot模块 data = self.collection.find({‘productId‘: {‘$regex‘: 63478}}) year = [] price = [] for du in data: year.append(du[‘sellDate‘]) price.append(du[‘authPrice‘]) #生成图表 pyplot.plot(year, price) #设置横坐标为year,纵坐标为population,标题为Population year correspondence pyplot.xlabel(‘time‘) pyplot.ylabel(productId+‘price‘) pyplot.title(productId+‘price time correspondence‘) #设置纵坐标刻度 pyplot.yticks([0, 150000, 250000, 750000, 900000]) #设置填充选项:参数分别对应横坐标,纵坐标,纵坐标填充起始值,填充颜色(可以有更多选项) pyplot.fill_between(year, price, 10, color = ‘blue‘) #显示图表 pyplot.show()
4.3 需求3:查看毒APP给各个年份发布鞋子数量的走势
def matplotlibYear(self): pipeline=[{$project:{year:{$substr:["$date",0,4]},"daily_count":1}}, {$group:{_id:"$year",year_count:{$sum:"$daily_count"}}}] data=self.collection.aggregate(pipeline) year = [] people = [] for x in data: year.append(x[‘_id‘]) people.append(x[‘year_count‘]) # 生成图表 pyplot.plot(year, people) # 设置横坐标为year,纵坐标为population,标题为Population year correspondence pyplot.xlabel(‘year‘) pyplot.ylabel(‘price‘) pyplot.title(‘year price ans‘) # 设置纵坐标刻度 pyplot.yticks([0, 5000, 10000, 15000, 20000, 25000, 30000]) # 设置填充选项:参数分别对应横坐标,纵坐标,纵坐标填充起始值,填充颜色(可以有更多选项) pyplot.fill_between(year, people, 10, color=‘red‘) # 显示图表 pyplot.show()
5.数据持久化
写入csv文件
6.附完整程序代码
# !/usr/bin/env python # -*- encoding: utf-8 -*- import execjs import requests import json import re import time import datetime import arrow import os import xlwt import pymongo class DuApp(object): def __init__(self): # 数据库 self.conn = pymongo.MongoClient(host=‘127.0.0.1‘, port=27017) self.db = self.conn.Duapp # 选择集合 self.collection = self.db.DuappPro self.headers = { ‘Host‘: "app.poizon.com", ‘User-Agent‘: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)" " Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.4.501 NetType/WIFI " "MiniProgramEnv/Windows WindowsWechat", ‘appid‘: "wxapp", ‘appversion‘: "4.4.0", ‘content-type‘: "application/x-www-form-urlencoded", ‘Accept-Encoding‘: "gzip, deflate", ‘Accept‘: "*/*", } self.img_path = ‘image‘ def get_recensales_list_url(self, lastId, productId): """ 构建最近购买记录url :param lastId: 起始页 :param productId: 商品id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘lastId{}limit20productId{}sourceAppapp19bc545a393a25177083d4a748807cc0‘.format( lastId, productId)) recensales_list_url = ‘https://app.poizon.com/api/v1/h5/product/fire/recentSoldList?‘ ‘productId={}&lastId={}&limit=20&sourceApp=app&sign={}‘.format(productId, lastId, sign) return recensales_list_url def get_brand_list_url(self, lastId, tabId): """ 构建商品品类列表 :param lastId: 起始页 :param tabId: 分类id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘lastId{}limit20tabId{}19bc545a393a25177083d4a748807cc0‘.format(lastId, tabId)) brand_list_url = ‘https://app.poizon.com/api/v1/h5/index/fire/shoppingTab?‘ ‘tabId={}&limit=20&lastId={}&sign={}‘.format(tabId, lastId, sign) return brand_list_url def get_product_detail_url(self, productId): """ 构建商品详情url :param productId: 商品id :return: """ with open(‘sign.js‘, ‘r‘, encoding=‘utf-8‘)as f: all_ = f.read() ctx = execjs.compile(all_) sign = ctx.call(‘getSign‘, ‘productId{}productSourceNamewx19bc545a393a25177083d4a748807cc0‘.format(productId)) product_detail_url = ‘https://app.poizon.com/api/v1/h5/index/fire/flow/product/detail?‘ ‘productId={}&productSourceName=wx&sign={}‘.format(productId, sign) return product_detail_url def get_brand_list_data(self, brand_list_url): """ 商品分类列表 :param url: 商品分类列表url :return: """ response = requests.get(url=brand_list_url, headers=self.headers) return response def get_product_detail_data(self, product_detail_url): """ 商品详情 :param url: 商品详情地址 :return: """ response = requests.get(url=product_detail_url, headers=self.headers) return response def get_recensales_list_data(self, recensales_list_url): """ 商品地址 :param recensales_list_url: 商品地址 :return: """ response = requests.get(url=recensales_list_url, headers=self.headers) return response def get_recensales_list_data(self, recensales_list_url): """ 商品地址 :param recensales_list_url: 商品地址 :return: """ response = requests.get(url=recensales_list_url, headers=self.headers) return response def getTime(self, flag, dayhourminute): ‘‘‘ 获取几小时之前,几分钟前,几天前,几个月前,及几年前的具体时间 flag, 1:天;2:小时;3:分钟;4:月,5:年 :param flag: 1:天;2:小时;3:分钟;4:月,5:年 :param dayhourminute: 整数值 :return: 具体时间 %Y-%m-%d %H:%M:%S ‘‘‘ tn = datetime.datetime.now() t = None ttime = ‘‘ if flag <= 1: if flag == 1: t = datetime.timedelta(days=dayhourminute) elif flag == 2: t = datetime.timedelta(hours=dayhourminute) elif flag == 3: t = datetime.timedelta(minutes=dayhourminute) strtime = tn - t ttime = strtime.strftime(‘%Y-%m-%d‘) else: dt = arrow.now() if flag == 4: ttime = dt.shift(months=-dayhourminute).format("YYYY-MM-DD") elif flag == 5: ttime = str(int( datetime.datetime.now().strftime( "%Y")) - dayhourminute) + "-" + datetime.datetime.now().strftime( "%m-%d") return ttime def download(self, picDict): # list for pic in picDict: url = pic[‘logoUrl‘] time_str = str(round(time.time() * 1000)) # 当前时间戳 img_name = time_str + ‘.png‘ try: path = os.path.join(self.img_path, img_name) if not os.path.exists(path): r = requests.get(url) r.raise_for_status() # 使用with语句可以不用自己手动关闭已经打开的文件流 with open(path, "wb") as f: # 开始写文件,wb代表写二进制文件 f.write(r.content) print("下载完成") else: print("文件已存在") except Exception as e: print("下载失败:" + str(e)) def get_data(self): # 商品品类列表 # app里面为购买menu 搜索下面table 这里只看了球鞋 # tabId 4 为球鞋品类, lastId 1 为翻页参数 for i in range(1, 999): try: logoUrlList = [] product_mongo_data_list = [] brand_list_url = self.get_brand_list_url(i, 4) # 商品品类列表data response = self.get_brand_list_data(brand_list_url) contents = json.loads(response.content, encoding=‘UTF-8‘) lists = contents.get(‘data‘) lists = lists.get(‘list‘) for product in lists: productId = product.get(‘productId‘) # productId = 47209 # 测试使用 # 商品详情 product_detail_url = self.get_product_detail_url(productId) # 商品详情data response = self.get_product_detail_data(product_detail_url) product_contents = json.loads(response.content, encoding=‘UTF-8‘) # 解析商品信息 logoUrl = product_contents.get(‘data‘) logoUrl = logoUrl.get(‘detail‘) logoUrl = logoUrl.get(‘logoUrl‘) # 图片 --主图 picDict = {‘productId‘: productId, ‘logoUrl‘: logoUrl} logoUrlList.append(picDict) # 放入一个集合 title = product_contents.get(‘data‘) title = title.get(‘detail‘) title = title.get(‘title‘) # 标题 sellDate = product_contents.get(‘data‘) sellDate = sellDate.get(‘detail‘) sellDate = sellDate.get(‘sellDate‘) # 发售日期 articleNumber = product_contents.get(‘data‘) articleNumber = articleNumber.get(‘detail‘) articleNumber = articleNumber.get(‘articleNumber‘) # 编号 color = product_contents.get(‘data‘) color = color.get(‘detail‘) color = color.get(‘color‘) # 颜色说明 authPrice = product_contents.get(‘data‘) authPrice = authPrice.get(‘detail‘) authPrice = authPrice.get(‘authPrice‘) # 价格 imageAndText = product_contents.get(‘data‘) imageAndText = imageAndText.get(‘detail‘) imageAndText = imageAndText.get(‘imageAndText‘) # 详情页 product_mongo_data = {‘productId‘: productId, ‘logoUrl‘: logoUrl, ‘title‘: title, ‘sellDate‘: sellDate, ‘articleNumber‘: articleNumber, ‘color‘: color, ‘authPrice‘: authPrice, ‘imageAndText‘: imageAndText} print(product_mongo_data) product_mongo_data_list.append(product_mongo_data) #批量存储 self.collection = self.db.DuappPro self.collection.insert_many(product_mongo_data_list) except Exception as e: print(e) print("something error") # 没有数据或者遇到异常,结束 break def text_save(self, filename, data): # filename为写入CSV文件的路径,data为要写入数据列表. file = open(filename, ‘w+‘, encoding=‘utf-8‘) for i in range(len(data)): s = str(data[i]).replace(‘[‘, ‘‘).replace(‘]‘, ‘‘) # 去除[],这两行按数据不同,可以选择 s = s.replace("‘", ‘‘).replace(‘,‘, ‘‘) + ‘\n‘ # 去除单引号,逗号,每行末尾追加换行符 file.write(s) file.close() print("保存文件成功") # 将数据写入新文件 def data_write(self, file_path, datas): f = xlwt.Workbook() sheet1 = f.add_sheet(u‘sheet1‘, cell_overwrite_ok=True) # 创建sheet # 将数据写入第 i 行,第 j 列 i = 0 for data in datas: for j in range(len(data)): sheet1.write(i, j, data[j]) i = i + 1 f.save(file_path) # 保存文件 def text_save(self,filename, data): # filename为写入CSV文件的路径,data为要写入数据列表. file = open(filename, ‘w+‘,encoding=‘utf-8‘) for i in range(len(data)): s = str(data[i]).replace(‘[‘, ‘‘).replace(‘]‘, ‘‘) # 去除[],这两行按数据不同,可以选择 s = s.replace("‘", ‘‘).replace(‘,‘, ‘‘) + ‘\n‘ # 去除单引号,逗号,每行末尾追加换行符 file.write(s) file.close() print("保存文件成功") # 将数据写入新文件 def data_write(self,file_path, datas): f = xlwt.Workbook() sheet1 = f.add_sheet(u‘sheet1‘, cell_overwrite_ok=True) # 创建sheet # 将数据写入第 i 行,第 j 列 i = 0 for data in datas: for j in range(len(data)): sheet1.write(i, j, data[j]) i = i + 1 f.save(file_path) # 保存文件 if __name__ == ‘__main__‘: duapp = DuApp() duapp.get_data() # duapp.text_save(‘duapp.txt‘,product_mongo_data_list) # duapp.data_write(‘duapp.xlsx‘,product_mongo_data_list) # 下载图片 # duapp.download(logoUrlList)
四、结论(10分)
1.经过对主题数据的分析与可视化,可以得到哪些结论?
1.1 通过分析可视化可知,耐克品牌在2018年6月的品牌价值是最高的时候。
1.2 通过分析可视化可知,Nike Rokit x Kyrie 5 Welcome Home "welcome Home" 全明星在2015年时价格最高,2016年价格最低,是入手的好时机。
1.3 通过分析可视化可知,2016年至2017年在APP刚发布时鞋子发布数量急速上升,2017-2018年突然上涨速度缓慢,通过查询知道因为这段时间平台出现盗版质量问题,口碑下降导致发布者减少,而在这之后APP内风气有所改善,2018-2019年鞋子发布数量继续上升。
2.对本次程序设计任务完成的情况做一个简单的小结。
本次作业,对爬虫和数据分析做了个整合,尽量将所学的知识都有用上,并且自己的课外通过bilibili视频教学学到了拓展知识,学习感觉很好,也切实体会到了爬虫在生活中的妙用,期待自己的每一次进步。
原文:https://www.cnblogs.com/chenwenyu/p/12057665.html