摘要
随着互联网的普及,网络购物已经成为了人们购物的首选,用户只需要在电商平台上进行自己喜欢的商品进行搜素,就可以得到成千上万条商品信息。而在购买商品时,商品价格就成为了用户的主要关注对象,而在一些特殊的日子里,例如618、双十一等等,许多商品都会降价以此来吸引顾客,降价的多少也成为了用户浏览商品的一个因素。因此,对商品降价的分析对用户是否购买该商品提供了对比性,具有一定的意义。该系统基于python的各种库来实现,分为获取京东商城口红商品的信息,进行可视化分析。
1 系统开发背景
随着互联网的普及,网络购物已经成为了人们购物的首选,用户只需要在电商平台上进行自己喜欢的商品进行搜素,就可以得到成千上万条商品信息。而在购买商品时,商品价格就成为了用户的主要关注对象,而在一些特殊的日子里,例如618、双十一等等,许多商品都会降价以此来吸引顾客,降价的多少也成为了用户浏览商品的一个因素。因此,对商品降价的分析对用户是否购买该商品提供了对比性,具有一定的意义。
基于网络爬虫的搜索引擎研究与实现,在当今网络中已非常普及。目前比较流行的搜索引擎代表有谷歌,百度,搜狗等。合理地使用好算法抓取页面,才是网络爬虫实现的核心。
爬虫又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动的抓取互联网中网页或者脚本,而影评搜索需要特定的收集,使得数据更加具有目的性。传统的爬虫是从一个或者多个初始url开始,不断的从当前页面抽取新的url进行搜索,直到满足一定条件才会停止。而聚集爬虫是根据一定的网页分析算法过滤于主体无关的链接,并将其放入等待抓取的url队列中,然后进行一定的分析,过滤,并建立索引,以便之后的查询和检索。网页的抓取策略可以分为深度优先,广度优先和最近优先三种。
2 系统相关技术介绍
本文主要是基于python语法和其强大的库来实现系统的多种功能。
2.1 Python语言
Python是一种计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。
Python在设计上坚持了清晰划一的风格,这使得Python成为一门易读、易维护,并且被大量用户所欢迎的、用途广泛的语言。
2.2 request库
Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,是网络爬虫中及其重要的组成成分。
2.3 lxml
lxml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据;lxml和正则一样,也是用C语言实现的,是一款高性能的python HTML、XML解析器,也可以利用XPath语法,来定位特定的元素及节点信息,HTML是超文本标记语言,主要用于显示数据,他的焦点是数据的外观,XML是可扩展标记语言,主要用于传输和存储数据,他的焦点是数据的内容
2.4 Matplotlib库
matplotlib是一个python的绘图库,它以各种硬拷贝格式和跨平台的交互式环境出版生成质量级别的图形,它能输出的图形包括折线图,散点图,直方图等,在数据可视化方面,matplotlib强悍的绘图能力能够帮助我们对数据形成非常清晰直观的认知。
2.5 pandas库
pandas是基于numpy的一种工具,该工具是为了解决数据分析任务而创建的。Pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
2.6 time库
Time库在爬虫的应用,主要是作为延迟或者限制爬虫频率的用途,对降低爬虫频率,对抗网站反爬虫措施意义重大
2.7 random库
随机数在计算机应用中十分常见,Python通过random库提供各种伪随机数,基本可以用于除加密解密算法外的大多数工程应用。这里的话主要是用来产生一个随机时间来使用,配合时间库降低爬虫频率。
3 系统分析与设计
3.1 系统功能模块组成
本系统主要由京东口红商品数据采集、京东口红商品数据处理、京东口红商品可视化等模块组成。
图1 系统功能模块图
这里将通过requests库结合xpath解析,来获取某东商城前20页,每页60个口红商品,共数百条条口红商品数据,包括商品的ID,名称,价格,店名,是否自营,地址链接,评论数(京东无直接销量数据,评论数相当于销量数据)以及好评率等数据,并使用pandas库对数据进行清洗与分析,matloplit进行可视化。
4 系统实现
本部分将对系统每个模块的实现和核心代码进行介绍。……
4.1 数据采集模块
本案例中采集的口红商品数据是在某东商城官网搜索框输入"口红",搜索得到的前20页口红商品的数据,如下图:
4.1.1 页面分析
通过下滑商品页面,可以发现有新的数据加载进来,点击跳转到页面2,发现url地址中page从1变成了3,所以说明,页面1中可能包含了page=1和page=2两个url地址。
点击新加载的元素,可以看到其url中的page已经由1变为2,说明页面1中前30个商品是page=1的url获取的,而后30个商品是page=2的url获取的。所以总结下来,我们要获取前20页共1000+的商品数据,page需要从1变到40。
# page从1到40,即可加载到前20个页面的商品__url = f"https://search.jd.com/Search?keyword=%E5%8F%A3%E7%BA%A2&qrst=1&wq=%E5%8F%A3%E7%BA%A2&sto
通过请求上述url网址,我们便可以遍历每一个商品,通过xpath解析,得到目标数据。实际操作过程中发现,评论数的数据无法获取(百度说是由于网页的异步渲染导致的),解决办法是借助某东的评价汇总网站,结合商品的ID,进行提取评论数及好评率等数据。
4.1.2 采集程序
经过多次尝试,最终使用以下程序采集成功。
首先导入需要用到的库,并对requests请求进行UA伪装:
# 导入库
import requests
import pandas as pd
from lxml import etree
import timeimport random
headers = { "Accept-Encoding": "Gzip", # 使用gzip压缩传输数据让访问更快 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36", # "Cookie": cookie }
采集每个url页面信息,获取评论数据信息(容易被封ip,建议将等待时间设置长一点)
# 网页是动态刷新的虽然页面1,2显示的url链接中page是1,3。但实际上第一页中前30个商品为page1,后30个商品为page2
def get_html(page):
url = f'https://search.jd.com/Search?keyword=%E5%8F%A3%E7%BA%A2&qrst=1&wq=%E5%8F%A3%E7%BA%A2&stock=1&pvid=148fb7e5c10b4f879ef1e245c89ecb24&page={page}'
r = requests.get(url, headers=headers)
time.sleep(random.randint(1, 3)) # 设置等待时间,预防被网站封IP
return r
# 获取总评数和好评率
def get_comments(pid):
comment_url = "https://club.jd.com/comment/productCommentSummaries.action?referenceIds="
comment_url += pid
comment_r = requests.get(comment_url,headers=headers)
time.sleep(random.randint(3, 5))# 设置等待时间,预防被网站封IP,亲测该网站很限制ip访问频率,所以等待时间设置久一点。
comment_sum = comment_r.json()["CommentsCount"][0]
return comment_sum
获取商品其他信息,这里使用了pandas中的dataframe数据结构提取数据,然后在存为csv格式。
采集过程如下
最终得到的数据如下:
Pandas读取数据,获得数据的结构为(1199行×8列)
import pandas as pddata = pd.read_csv('京东口红信息.csv')# 给数据加上表头
data.columns=['ID','name','price','store_name','self_run','url_list','CommentCount','GoodRate']
print(data.shape) # 输出结果为: (1199,8)
4.2 数据清洗
数据清洗包括将重复的数据进行删除;对评论数中的'万'及'+'进行替换,从而让程序能更好的分析、比较数据;提取某东自营的数据,并将商家名中的品牌提取出来,统计某东自营在售的销量>10万+的口红品牌。
4.2.1 删除重复数据
import pandas as pddata = pd.read_csv('京东口红信息.csv')
# 给数据加上表头
data.columns=['ID','name','price','store_name','self_run','url_list','CommentCount','GoodRate']
# 去除重复值data = data.drop_duplicates()print(data)
去掉重复值之后,保留了1018个有效数据
4.2.2 替换'万'字
# 将'万'字替换data['CommentCount'] = data['CommentCount'].str.replace('+','').str.replace('万','0000')print(data.CommentCount)
打印输出评价数量列,替换成功
4.2.3 提取自营店及口红品牌
# 提取自营商家及口红品牌data = data[data['store_name'].str.contains('京东自营')]data.reset_index(inplace=True)
data1 = data.store_name.str.split('京东自营',expand = True)data1.columns=['品牌','店名']data['品牌'] = data1['品牌']data = data.drop(columns='index')data.to_csv('自营商品信息提取.csv',index=False)print(data)
处理后数据如下:
4.3 数据统计
4.3.1 商品价格分布
如下图可知,口红价格多分布在500以下,0-250之间的最多。
实现代码:
import pandas as pd
import matplotlib.pyplot as plt
# 读取所有数据
df1 = pd.read_csv('去除重复值后数据.csv')# 商品价格分布df1.price.plot.hist(bins=20)plt.show()
4.3.1 不同价格区间分布
按照0-100,100-200,200-300,300-600,600-1000,1000+分类统计,可以发现0-100区间的口红占比最多,达到了34.1%!
实现代码如下:
bins= [0,100,200,300,600,1000,999999]price_Num = df1['price'].groupby(pd.cut(df1.price, bins= bins)).count().to_frame('数量')print(price_Num)labels = price_Num.indexsizes = price_Num['数量']explode = (0.1,0, 0, 0, 0, 0)
fig1, ax1 = plt.subplots(figsize=(10,8))patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90)
plt.tight_layout()plt.show()
4.3.2 评论数分布(销量相关)占比图
由下图可知:
大多数销量在1万-10万之间,占比达31.1%,100万+的商品占比15%!
实现代码如下:
bins= [0,100,200,500,1000,5000,10000,100000,1000000]comment_Num = df1['CommentCount'].groupby(pd.cut(df1.CommentCount, bins= bins)).count().to_frame('数量')labels = list(comment_Num.index)[:7]labels.extend(['1000000+'])comment_Num = df1['CommentCount'].groupby(pd.cut(df1.CommentCount, bins= bins, labels=labels)).count().to_frame('数量')labels = comment_Num.indexsizes = comment_Num['数量']explode = (0,0, 0, 0, 0, 0,0.1,0)
fig1, ax1 = plt.subplots(figsize=(10,8))patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90)plt.tight_layout()plt.show()
4.3.3 统计销量>10万+的自营口红品牌
打印输出十万加的口红品牌:
'兰蔻', 'YSL圣罗兰', '迪奥(Dior)美妆', 'MAC魅可', 'ARMANI阿玛尼美妆', 'GIVENCHY纪梵希', '花西子', '迪奥(Dior)海外', '美宝莲', '卡姿兰', '欧莱雅', '完美日记', '3CE', 'colorkey', 'Pink Bear'
代码实现如下:
# 读取所有数据df1 = pd.read_csv('自营商品信息提取.csv')
df2 = df1[df1['CommentCount']>=100000]
lst1 = df2['品牌'].valuestemp = [][temp.append(i) for i in lst1 if not i in temp]
print(temp)
4.3.4 自营口红品牌的商品种类
如下图
代码如下:
df1 = pd.read_csv('自营商品信息提取.csv')
df2 = df1.groupby(by='品牌').count()['ID']data = df2.sort_values(ascending=False)
print(data)
4.3.5 取口红种类前20的品牌进行绘制条形图
自营商品中,种类排名前20的品牌如下图所示
代码实现如下:
df1 = pd.read_csv('自营商品信息提取.csv')
df2 = df1.groupby(by='品牌').count()['ID']data = df2.sort_values(ascending=True)
x = data[-21:-1].indexy = data[-21:-1].values
plt.barh(x,y)plt.xlabel('商品种类')
plt.tight_layout()plt.show()
5 系统开发总结
本系统主要介绍了如何用python爬取某东口红前20页的商品数据,并对数据进行清洗和分析。从三个层面分析,结构简单,脉络清晰。在开发过程中自然遇到很多问题,通过查阅书籍,向同学求助,网上查询,这些问题都能够逐一解决。
当然,此系统还存在诸多不足之处,涉及反爬措施不足等,后续会加以完善。
参考文献
[1] 崔庆才.python3网络爬虫实战演练[M].北京:人民邮电出版社,2018: 4-7.
[2] 刘瑜.python零基础到项目实战[M].北京:中国水利水电出版社,2018: 10-1.
[3] 明日科技.python项目开发样例集锦[M].吉林:吉林大学出版社,2019: 3-1.
[4] 连晓峰.python强化实战[M].北京:机械工业出版社,2019: 1-1.
[5] 包永帅.python应用开发实战[M].北京:人民邮电出版社,2018: 6-1.
[6] 王国辉.python从入门到项目实战[M].吉林:吉林大学出版社,2018: 8-1.