本文实现一个非常有趣的项目,这个项目是关于胸罩销售数据分析的。是网络爬虫和数据分析的综合应用项目。本项目会从天猫抓取胸罩销售数据,并将这些数据保存到SQLite数据库中,然后对数据进行清洗,最后通过SQL语句、Pandas和Matplotlib对数据进行数据可视化分析。我们从分析结果中可以得出很多有的结果,例如,中国女性胸部标准尺寸是多少;胸罩上胸围的销售比例;哪个颜色的胸罩最受女性欢迎。

1. 项目效果展示

本项目涉及到网络技术、网络爬虫技术、数据库技术、数据分析技术、数据可视化技术。首先应该运行tmallbra.py脚本文件从天猫抓取胸罩销售数据,并将这些数据保存到SQLite数据库中。接下来可以执行analyze目录中的相应Python脚本文件进行可视化数据分析。下面是一些分析结果展示。

图1:ABCD罩杯胸罩销售比例

图2:胸罩销售比例(罩杯和上胸围综合指标)

图3:胸罩销售比例(按颜色分析)31

图4:罩杯和下胸围分布直方图

其实Google和淘宝也给出了类似的分析结果。Google曾给出了一幅世界女性胸部尺寸分布地图 ,从地图中可以明显看出中国大部分地区呈现绿色(表示平均胸部尺寸为A罩杯),少部分地区呈现蓝色(表示平均胸部尺寸为B罩杯),这也基本验证了图2所示的统计结果:中国大部分女性胸部尺寸是75B和75A。

再看一下淘宝给出的胸罩(按罩杯和上胸围统计)销售比例柱状图。

图5:淘宝胸罩销售比例柱状图(按罩杯和上胸围统计)

从淘宝给出的数据可以看出,销售最好的胸罩尺寸是75B,这个统计结果虽然销售比例不同(取的样本不同而导致的),但按销售数据排行,这个分析结果与本项目的统计结果(图2)基本吻合。

2. 天猫胸罩销售数据分析

这里的销售数据其实就是评论数据。用户购买一件商品并发了评论,就会记录销售数据。分析销售数据的第一步就是要搞明白数据是怎么跑到客户端浏览器上的。通常来讲,浏览器从服务端获取数据有两种方式:同步和异步。同步就是数据随HTML代码一同发送到客户端,不过现在的大型网站很少有用同步方式传输数据了。异步方式是HTML代码与数据分别发送到客户端,数据一般是JSON格式,通过AJAX技术获取,然后再使用JS将获取到的数据显示在HTML中的元素上。不过有时会加一些反爬虫技术,或处于其他目的,异步数据可能并不是纯的JSON格式,例如,有可能是一段JavaScript代码,或在JSON格式数据中加一些其他的内容。不过这些基本都没用,加的内容肯定是有规律的,否则自己的程序都无法读了。

现在进到天猫商城官网https://www.tmall.com,在搜索框输入“胸罩”,点击“搜索”按钮进行搜索。随便找一个销售胸罩的店铺点进去。然后在页面的右键菜单中点击“检查”菜单项,打开调试窗口,切换到“Network”标签页。接下来查看商品的评论,会在“Network”标签页显示评论信息要访问的Url。在上方的搜索框输入“list_detail”,会列出所有已“list_detail”作为前缀的Url。这些Url就是用AJAX异步获取的评论数据。点击某个Url,会在右侧显示如图6所示的数据,很明显,这些数据与JSON非常像,不过加了一些前缀以及其他信息,估计是要满足一些特殊需要。

图6:天猫评论数据

在返回的评论数据中,rateList就是我们需要的信息,rateList列表中一共是20个对象,包含了20条评论数据,也就是说,通过这个Url,每次返回了20条评论数据。

在Url中还有两个HTTP GET请求字段对我们有用。

• itemId:当前商品的ID,通过这个字段,可以获得指定商品的评论数

据(不光是胸罩)。

• currentPage:当前的页码,从1开始。通过这个字段,可以获得更多的评论数据。

3.抓取天猫胸罩销售数据

既然对天猫胸罩的评论数据的来源已经非常清楚了,本节就抓取这些数据。在tmallbra.py脚本文件中有一个核心函数,用于抓取指定商品的某一页评论数据。

def getRateDetail(itemId,currentPage):
# Url最后的callback字段是用于天猫网站内部回调的,和我们没关系,不过这个字段的值关系到
# 返回数据的前缀,我们可以利用这个值去截取返回数据
url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=' + str(itemId) +
'&spuId=837695373&sellerId=3075989694&order=3&currentPage=' + str(currentPage) +
'&append=0... ...&callback=jsonp1278'
r = http.request('GET',url,headers = headers)
# 返回数据时GB18030编码,所以要用这个编码格式进行解码
c = r.data.decode('GB18030')
# 下面的代码将返回的评论数据转换为JSON格式
c = c.replace('jsonp1278(','')
c = c.replace(')','')
c = c.replace('false','"false"')
c = c.replace('true','"true"')
# 将JSON格式的评论数据转换为字典对象
tmalljson = json.loads(c)
return tmalljson

4. 抓取胸罩商品列表

应用让爬虫自动选取胸罩商品,而不是我们一个一个挑。所以可以利用如下的天猫商城的搜索页面Url进行搜索,按销量从大到小排列。

https://list.tmall.com/search_product.htm... ...

这个Url不需要传递任何参数,本项目只取第一个商品页的所有商品。在tmallbra.py脚本文件中有一个而核心函数getProductIdList,用于返回第一个商品页的所有商品ID(以列表形式返回)。

def getProductIdList():
url = 'https://list.tmall.com/search_product.htm... ...'
r = http.request('GET', url,headers = headers)
c = r.data.decode('GB18030')
soup = BeautifulSoup(c,'lxml')
linkList = []
idList = []
# 用Beautiful Soup提取商品页面中所有的商品ID
tags = soup.find_all(href=re.compile('detail.tmall.com/item.htm'))
for tag in tags:
linkList.append(tag['href'])
linkList = list(set(linkList))
for link in linkList:
aList = link.split('&')
# //detail.tmall.com/item.htm?id=562173686340
# 将商品ID添加到列表中
idList.append(aList[0].replace('//detail.tmall.com/item.htm?id=',''))
return idList

4.将抓取的销售数据保存到SQLite数据库中

剩下的工作就很简单了,只需要对商品ID列表迭代,然后对每一个商品的评论数据进行抓取,天猫每个商品最多可以获得99页评论,最大评论页数可以通过getLastPage函数获得。

def getLastPage(itemId):
tmalljson = getRateDetail(itemId,1)
return tmalljson['rateDetail']['paginator']['lastPage']

下面的代码会抓取商品搜索第一页的所有胸罩商品的评论数据,并将这些数据保存到SQLite数据库中。

# 对商品ID进行迭代
while initial < len(productIdList):
try:
itemId = productIdList[initial]
print('----------',itemId,'------------')
maxnum = getLastPage(itemId)
num = 1
while num <= maxnum:
try:
# 抓取某个商品的某页评论数据
tmalljson = getRateDetail(itemId, num)
rateList = tmalljson['rateDetail']['rateList']
n = 0
while n < len(rateList):
# 颜色分类:H007浅蓝色加粉色;尺码:32/70A
colorSize = rateList[n]['auctionSku']
m = re.split('[:;]',colorSize)
rateContent = rateList[n]['rateContent']
color = m[1]
size = m[3]
dtime = rateList[n]['rateDate']
# 将抓取的数据保存到SQLite数据库中
cursor.execute('''insert into t_sales(color,size,source,discuss,time)
values('%s','%s','%s','%s','%s') ''' % (color,size,'天猫',rateContent,dtime))
conn.commit()
n += 1
print(color)
print(num)
num += 1
except Exception as e:
continue
initial += 1
except Exception as e:
print(e)

5. 数据清洗

如果读者使用前面介绍的方法从天猫和京东抓取了胸罩销售数据,现在我们已经有了一个SQLite数据库,里面有一个t_sales表,保存了所有抓取的数据,如图7所示。

图7:保存到数据库中的胸罩销售数据

从销售数据可以看出,网络爬虫抓取了颜色(color)、尺寸(size)、来源(source)、评论(discuss)和时间(time)五类数据。当然还可以抓取更多的数据,这里只为了演示数据分析的方法,所以并没有抓取那么多的数据。

不过这五类数据有些不规范,本项目值考虑color和size,所以先要对这两类数据进行清洗。由于每个店铺,每个商品的颜色叫法可能不同,所以需要将这些颜色值统一一下。例如,所有包含“黑”的颜色值都可以认为是黑色。所以可以新建立一个color1字段(尽量不要修改原始数据),将清洗后的颜色值保存到color1字段中。然后可以使用下面的SQL语句对颜色值进行清洗。

update t_sales  set color1 = '黑色'  where color like '%黑%' ;
update t_sales set color1 = '绿色' where color like '%绿%' ;
update t_sales set color1 = '红色' where color like '%红%' ;
update t_sales set color1 = '白色' where color like '%白%' ;
update t_sales set color1 = '蓝色' where color like '%蓝%' ;
update t_sales set color1 = '粉色' where color like '%粉%' and color1 is null ;
update t_sales set color1 = '青色' where color like '%青%' ;
update t_sales set color1 = '卡其色' where color like '%卡其%' ;
update t_sales set color1 = '紫色' where color like '%紫%' ;
update t_sales set color1 = '肤色' where color like '%肤%' ;
update t_sales set color1 = '水晶虾' where color like '%水晶虾%' ;
update t_sales set color1 = '玫瑰色' where color like '%玫瑰%' ;
update t_sales set color1 = '银灰' where color like '%银灰%' ;

胸罩尺寸清洗的方式与胸罩颜色类似,大家可以自己通过SQL语句去完成。

清洗完的结果如图8所示。

图8:清洗后的数据

6. 用SQL语句分析胸罩(按罩杯尺寸)的销售比例

既然销售数据都保存在SQLite数据库中,那么我们不妨先用SQL语句做一下统计分析。本节将对胸罩按罩杯的销售量做一个销售比例统计分析。由于抓取的数据没有超过D罩杯的,所以做数据分析时就不考虑D以上罩杯的胸罩销售数据了。这里只考虑A、B、C和D罩杯胸罩的销售数据。

本节要统计的是某一个尺寸的胸罩销售数量占整个销售数量的百分比,这里需要统计和计算如下3类数据。

• 某一个尺寸的胸罩销售数量。

• 胸罩销售总数量

• 第1类数据和第2类数据的差值(百分比)

这3类数据完全可以用一条SQL语句搞定,为了同时搞定A、B、C和D罩杯的销售比例,可以用4条类似的SQL语句,中间用union all连接。

select 'A' as 罩杯,printf("%.2f%%",(100.0 * count(*)/ (select count(*) from t_sales  where size1 is not null)))  as 比例, count(*) as 销量 from t_sales where size1='A'
union all
select 'B',printf("%.2f%%",(100.0 * count(*)/ (select count(*) from t_sales where size1 is not null))) , count(*) as c from t_sales where size1='B'
union all
select 'C',printf("%0.2f%%",(100.0 * count(*)/ (select count(*) from t_sales where size1 is not null))) , count(*) as c from t_sales where size1='C'
union all
select 'D',printf("%.2f%%",(100.0 * count(*)/ (select count(*) from t_sales where size1 is not null))) , count(*) as c from t_sales where size1='D'
order by 销量 desc

上面的SQL语句不仅加入了销售比例,还加入了销售数量,并且按销量降序排列。这些SQL语句需要考虑size1字段空值的情况,因为抓取的少部分销售记录并没有罩杯尺寸数据。执行上面的SQL语句后,会输出如图9所示的查询结果。

图9:用SQL语句统计胸罩(按罩杯尺寸)销售比例

其他的销售数据的分析类似。

7. 用Pandas和Matplotlib分析对胸罩销售比例进行可视化分析

既然Python提供了这么好的Pandas和Matplotlib,那么就可以完全不使用SQL语句进行数据分析了。可以100%使用Python代码搞定一切。

本节将使用Pandas完成与上一节相同的数据分析,并使用Matplotlib将分析结果以图形化方式展现出来。

Pandas在前面的章节已经讲过了,这里不再深入介绍。本次分析主要使用了groupby方法按罩杯(size1)分组,然后使用count方法统计组内数量,最后使用insert方法添加了一个“比例”字段。

from pandas import *
from matplotlib.pyplot import *
import sqlite3
import sqlalchemy
# 打开bra.sqlite数据库
engine = sqlalchemy.create_engine('sqlite:///bra.sqlite')
rcParams['font.sans-serif'] = ['SimHei']
# 查询t_sales表中所有的数据
sales = read_sql('select source,size1 from t_sales',engine)
# 对size1进行分组,并统计每一组的记录数
size1Count = sales.groupby('size1')['size1'].count()
print(size1Count)
# 计算总销售数量
size1Total = size1Count.sum()
print(size1Total)
print(type(size1Count))
# 将Series转换为DataFrame
size1 = size1Count.to_frame(name='销量')
print(size1)
# 格式化浮点数
options.display.float_format = '{:,.2f}%'.format
# 插入新的“比例”列
size1.insert(0,'比例', 100 * size1Count / size1Total)
print(size1)
# 将索引名改为“罩杯”
size1.index.names=['罩杯']
print(size1) # 数据可视化
print(size1['销量'])
# 饼图要显示的文本
labels = ['A罩杯','B罩杯','C罩杯','D罩杯']
# 用饼图绘制销售比例
size1['销量'].plot(kind='pie',labels = labels, autopct='%.2f%%')
# 设置长宽相同
axis('equal')
legend()
show()

运行程序,会看到在窗口上绘制了如图10所示的胸罩销售比例。用Pandas分析得到的数据与使用SQL分析得到的数据完全相同。

图10:胸罩销售比例(按罩杯尺寸)

其他分析也可以使用Pandas,可视化使用Matplotlib。这两个工具真是个强大的东西。祝大家学习愉快

Python网络爬虫实战:根据天猫胸罩销售数据分析中国女性胸部大小分布的更多相关文章

  1. 关于Python网络爬虫实战笔记③

    Python网络爬虫实战笔记③如何下载韩寒博客文章 Python网络爬虫实战笔记③如何下载韩寒博客文章 target:下载全部的文章 1. 博客列表页面规则 也就是, http://blog.sina ...

  2. python网络爬虫实战PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:vg1y python网络爬虫实战帮助读者学习Python并开发出符合自己要求的网络爬虫.网络爬虫,又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取互联网信息的程序或者脚 ...

  3. 关于Python网络爬虫实战笔记①

    python网络爬虫项目实战笔记①如何下载韩寒的博客文章 python网络爬虫项目实战笔记①如何下载韩寒的博客文章 1. 打开韩寒博客列表页面 http://blog.sina.com.cn/s/ar ...

  4. Python网络爬虫实战(一)快速入门

    本系列从零开始阐述如何编写Python网络爬虫,以及网络爬虫中容易遇到的问题,比如具有反爬,加密的网站,还有爬虫拿不到数据,以及登录验证等问题,会伴随大量网站的爬虫实战来进行. 我们编写网络爬虫最主要 ...

  5. python网络爬虫实战之快速入门

    本系列从零开始阐述如何编写Python网络爬虫,以及网络爬虫中容易遇到的问题,比如具有反爬,加密的网站,还有爬虫拿不到数据,以及登录验证等问题,会伴随大量网站的爬虫实战来进行. 我们编写网络爬虫最主要 ...

  6. 利用Python网络爬虫抓取微信好友的所在省位和城市分布及其可视化

    前几天给大家分享了如何利用Python网络爬虫抓取微信好友数量以及微信好友的男女比例,感兴趣的小伙伴可以点击链接进行查看.今天小编给大家介绍如何利用Python网络爬虫抓取微信好友的省位和城市,并且将 ...

  7. Python网络爬虫实战入门

    一.网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序. 爬虫的基本流程: 发起请求: 通过HTTP库向目标站点发起请求,也就是发送一个Request ...

  8. Python网络爬虫实战(三)照片定位与B站弹幕

    之前两篇已经说完了如何爬取网页以及如何解析其中的数据,那么今天我们就可以开始第一次实战了. 这篇实战包含两个内容. * 利用爬虫调用Api来解析照片的拍摄位置 * 利用爬虫爬取Bilibili视频中的 ...

  9. Python网络爬虫实战(二)数据解析

    上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是 ...

随机推荐

  1. [Python][小知识][NO.4] wxPython 字体选择对话框(O.O 不知道放到那里就放到这个分类的)

    1.前言 O.O 前两天回家浪了两天,断更了 哎~~~ o.o 有时候,有木有想改标签或编辑框中内容的字体呀?(o.o 反正我是没有). wxpython也可以说是所在的操作系统,有字体选择器,给我们 ...

  2. python3接收、解析邮件

    邮件接收 python3可以使用poplib.POP3进行邮件接收,具体如下: import poplib from email.parser import Parser def get_email( ...

  3. [20190219]那个更快(11g).txt

    [20190219]那个更快(11g).txt --//前几天测试11g Query Result Cache RC Latches时,链接http://blog.itpub.net/267265/v ...

  4. c/c++ 标准库 map set 大锅炖

    标准库 map set 大锅炖 一,关联容器有哪些 按关键字有序保存元素 map 保存key和value set 只保存key mulutimap key可以重复出现 multiset key可以重复 ...

  5. Entity Framework 5.0.0 Function Import 以及 ODP. NET Implicit REF CURSOR Binding使用简介

    源代码 概要: 1,说明如何使用Entity Framework中的function import功能. 2,说明如何使用ODP.NET的隐式REF CURSOR绑定(implicit REF CUR ...

  6. Gradle: Gradle Wrapper

    [Gradle 安装] 安装完毕后,记得设置一下环境变量.Environment Variables:GRADLE_HOME=D:\Program Files\Gadle\gradle-4.7Path ...

  7. esxi网络中虚拟机的相关操作

    一个虚拟机的克隆就是原始虚拟机全部状态的一个备份或镜像.克隆的过程不影响原始虚拟机.而快照指的是虚拟磁盘在某一特定时间点的副本.执行快照将保留虚拟机的状况和数据. 一.实验拓扑图: 目标:克隆虚拟机, ...

  8. Ecto 总结

    ecto 简介 ecto 相当于 elixir 的 ORM,但是得益于 elixir 语言,和传统的 ORM 相比,更加简洁和强大. ecto 主要分为 4 部分: Repo: 这是和真正数据库交互的 ...

  9. Emacs中多个golang项目的配置方法

    概述 最近使用golang开发项目时, 发现有时需要同时进行多个golang项目. 在这种情况下, 如果把所有的项目都放在 GOPATH 之下, 不仅管理麻烦(因为各个项目需要提交到不同的代码库), ...

  10. vue指令详解和自定义指令

    在vue中,指令以v-开头,是一种特殊的自定义行间属性,指令的职责就是其表达式的值改变时相应地将某些行为应用到DOM上 指令使用的示例 在下面的运行结果中可以看到,v-html是可以解析html标签的 ...