一、数据来源
在京东上,我们无法直接获得具体的销售数据。曲线救国,在京东上若超过60天没有做出评价,系统将自动匹配好评,我们可以通过评论数据间接得到鞋子的销售数据。通过对评论的爬取,筛选出我们想要获取的信息。
1.找到评论区的URL
(1)鼠标右击选择检查,打开程序员调试窗口,点击network(网络)
(2)刷新当前页面
(3)复制一小段评论区内容,然后在程序员调试窗口点击放大镜
(4)点击刷新小圆圈
(5)点击查询结果的第二行,跳转到对应的请求
(6)点击Headers,找到Request URL即评论区数据背后的URL
2.爬取京东数据
(1) 引入Python工具包requests;
(2) 使用工具包中的get方法,向服务器发起请求;
(3) 打印输出请求回来的数据;
(4) 将数据整理成Json格式:以大括号开头和结尾,使用replace把任何不想要的数据替换成一个新值;
(5) 找到目标数据值对应的名字,发现评论数据都在comments里面,将我们想要的数据暂时存放在列表中;
(6) 经过上面几个步骤,我们只能得到10条数据(一页),我们可以通过修改url进行翻页,比较第一页和第二的页的地址我们可发现一些共同点和不同点,通过字符串的拼接,将url进行更新,达到爬取多页的目的。
3.数据储存
这里我们将数据储存为CSV格式的文件,由于网络的原因,在爬取数据的时候会报错,这里我们将写入的形式改为追加写(a)
4 数据在评论区下载
二、数据描述
经过前面两个步骤的操作,我们初步获取获取到了数据
数据共1000条(共100页的评论),每条数据包括鞋子的颜色、型号和时间
1. VSCode下打开
这个是在VSCode下进行打开的数据,这也是我们要处理时的数据的样子
2. Excel进行打开
下面使用Excel进行打开,这样看起来是比较直观的
三、数据处理过程
我们要对获取到的数据进行处理,以便进行可视化分析
1. 从CSV文件中读取数据
这里我们使用pandas库下的DataFrame类进行CSV文件的读取,返回读取的内容
2. 对不同颜色的鞋子的销量进行统计
利用字典对数据进行统计,先按照数量进行排序,再转换为列表,返回列表
将返回的列表写入到CSV文件中
打开CSV文件,我们可以看到下面的数据
3. 统计各个型号的鞋子数量
利用字典对数据进行统计,先按照数量进行排序,再转换为列表,返回列表
将返回的列表写入到CSV文件中
打开CSV文件,我们可以看到下面的数据
4. 统计每个月的销量
利用字典对数据进行统计,先按照数量进行排序,再转换为列表,返回列表
PS:为了方便统计,我们需要对日期进行处理,先从字符串转为datetime,在转换为我们所需要的格式;也可以直接对字符串进行切片
将返回的列表写入到CSV文件中
打开CSV文件,我们可以看到下面的数据
四、可视化展示及分析结果
1. 对不同颜色的鞋子的销量进行统计
饼图
从上图我们可以直观的感受到曜石黑/361度白这个颜色最受欢迎,商家可以考虑增加货量,避免缺货;361度白/曜石黑的销量最低,可以减少货量,避免货物囤积。
2. 对不同型号的鞋子的销量进行统计
饼图
就鞋号来说,41,42,43#的鞋码占据了绝大部分,可以增加这部分鞋码的货量
3. 对鞋子每月销量的分析
由于数据过多,需要旋转下标
折线图/散点图
我们可以通过上图判断销量随月份变化的趋势
条形图
五、附录(代码)
1. data_get_spider(获取数据)
import csv
import requests
import json
def get_data(url):
resp = requests.get(url)
content = resp.text
rest = content.replace('fetchJSON_comment98(', '').replace(');', '')
json_data = json.loads(rest) # 将json格式的字符串转换成python的数据类型,解码过程
comments = json_data['comments']
data = []
for item in comments:
color = item['productColor']
size = item['productSize']
time = item['creationTime']
data.append([color, size, time])
# 若存在文件,则打开csv文件,若不存在,则新建文件
# 若不设置newline="",则每行数据会隔一行空包行
csvfile = open("E:\\Python\\大作业\\data.csv",
"a", newline="", encoding='utf-8') # w是覆盖形写入,a是追加写入
# 将文件加载到csv对象中
writer = csv.writer(csvfile)
# 数据写入
writer.writerows(data)
# 关闭csv对象
csvfile.close()
if __name__ == '__main__':
url = 'https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=8240128&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1'
for i in range(100): # 爬取100页评论
get_data(url)
# 更新URL
url = 'https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=8240128&score=0&sortType=5&page=' + \
str(i)+'&pageSize=10&isShadowSku=0&rid=0&fold=1'
2. data_analysis(数据分析处理)
# -*-encoding:utf-8-*-
import csv
from datetime import datetime
import pandas as pd
def read_csv(filename):
"""接收文件名,读取csv文件"""
df = pd.DataFrame(pd.read_csv(filename)) # 读取数据
return df
def count_col(data):
"""统计各个颜色的鞋子数量"""
dict_col = {}
for row in data['颜色']:
colour = row
dict_col[colour] = dict_col.get(colour, 0)+1
ls = list(sorted(dict_col.items(), key=lambda x: x[1]))
return ls
def write_count_col(data):
csvfile = open("E:\\Python\\大作业\\count_col.csv",
"w", newline="", encoding='utf-8') # w是覆盖形写入,a是追加写入
# 将文件加载到csv对象中
writer = csv.writer(csvfile)
# 数据写入
writer.writerows(data)
# 关闭csv对象
csvfile.close()
def count_size(data):
"""统计各个型号的鞋子数量"""
dict_size = {}
for row in data['型号']:
size = row
dict_size[size] = dict_size.get(size, 0)+1
ls = list(sorted(dict_size.items(), key=lambda x: x[0]))
return ls
def write_count_size(data):
csvfile = open("E:\\Python\\大作业\\count_size.csv",
"w", newline="", encoding='utf-8') # w是覆盖形写入,a是追加写入
# 将文件加载到csv对象中
writer = csv.writer(csvfile)
# 数据写入
writer.writerows(data)
# 关闭csv对象
csvfile.close()
def count_monthly_sales(data):
"""统计每个月的销量"""
# 统计每月销量
ls = []
for date in data['日期']:
# 先转为datetime类型,再进行转换
d = datetime.strptime(date, '%Y-%m-%d %H:%M:%S').strftime('%Y-%m')
ls.append(d)
dict_sales = {}
for date in ls:
dict_sales[date] = dict_sales.get(date, 0)+1
ls = list(sorted(dict_sales.items(), key=lambda x: x[0]))
return ls
def write_count__monthly_sales(data):
csvfile = open("E:\\Python\\大作业\\count_monthly_sales.csv",
"w", newline="", encoding='utf-8') # w是覆盖形写入,a是追加写入
# 将文件加载到csv对象中
writer = csv.writer(csvfile)
# 数据写入
writer.writerows(data)
# 关闭csv对象
csvfile.close()
if __name__ == '__main__':
filename = 'data copy.csv'
data = read_csv(filename)
# 将每个颜色鞋子的数量写入CSV文件
color = count_col(data)
write_count_col(color)
# 将每个型号鞋子的数量写入CSV文件
size = count_size(data)
write_count_size(size)
# 将每个月的销量写入CSV文件
sales = count_monthly_sales(data)
write_count__monthly_sales(sales)
3. show_col_pie(使用饼图展示颜色)
import matplotlib.pyplot as plt
# 这两行代码解决中文标题乱码的问题
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
def show_pie(labels, sizes, explode):
"""使用饼图展示"""
plt.pie(sizes, explode=explode, labels=labels,
autopct='%1.1f%%', shadow=False, startangle=90)
plt.title('不同颜色的鞋子的销量分析') # 标题
plt.legend() # 显示图例
plt.axis('equal') # 使饼图保持圆形
plt.show() # 展示
def open_count_col(filename):
csvfile = open(filename, "r", encoding='utf-8') # w是覆盖形写入,a是追加写入
labels = []
sizes = []
for row in csvfile:
color = row.split(',')[0]
count = row.split(',')[1]
labels.append(color)
sizes.append(count)
labels = tuple(labels)
explode = (0, 0, 0, 0, 0.1)
show_pie(labels, sizes, explode)
if __name__ == "__main__":
filename = 'count_col.csv'
open_count_col(filename)
4. show_size_pie (使用饼图展示型号)
import matplotlib.pyplot as plt
# 这两行代码解决中文标题乱码的问题
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
def show_pie(labels, sizes, explode):
"""使用饼图展示"""
plt.pie(sizes, explode=explode, labels=labels,
autopct='%1.1f%%', shadow=False, startangle=90)
plt.title('不同型号的鞋子的销量分析') # 标题
plt.legend() # 显示图例
plt.axis('equal') # 使饼图保持圆形
plt.show() # 展示
def open_count_col(filename):
csvfile = open(filename, "r", encoding='utf-8') # w是覆盖形写入,a是追加写入
labels = []
sizes = []
for row in csvfile:
color = row.split(',')[0]
count = row.split(',')[1]
labels.append(color)
sizes.append(count)
labels = tuple(labels)
explode = (0, 0, 0, 0.1, 0, 0, 0)
show_pie(labels, sizes, explode)
if __name__ == "__main__":
filename = 'count_size.csv'
open_count_col(filename)
5. show_sales_plot(使用折线和散点展示月销量)
import matplotlib.pyplot as plt
# 这两行代码解决中文标题乱码的问题
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
def open_csv(filename):
"""打开文件,返回读取的内容"""
f = open(filename, "r")
x = f.readlines()
f.close()
return x
def analyse(data):
"""对数据进行分组处理"""
sales = [] # y
dates = [] # x
for line in data:
date = line.strip().split(',')[0]
sale = eval(line.strip().split(',')[1]) # 要改为数字类型才能按顺序排列
dates.append(date)
sales.append(sale)
show_plot(dates, sales)
def show_plot(dates, sales):
"""绘制图形"""
# 设置线宽
plt.plot(dates, sales, '--', linewidth=4) # 虚线
plt.plot(dates, sales, 'ob', linewidth=4)
# 设置图表标题,并给坐标轴添加标签
plt.title("每月销量折线图",
fontsize=20)
plt.xlabel("时间", fontsize=12)
plt.ylabel("销量", fontsize=12)
# 设置坐标轴刻度标记的大小
plt.tick_params(axis='both',
labelsize=10)
# 旋转坐标轴标签
plt.xticks(rotation=45)
plt.show()
if __name__ == '__main__':
filename = 'count_monthly_sales.csv'
data = open_csv(filename)
analyse(data)
6. show_sales_bar(使用条形图展示月销量)
import matplotlib.pyplot as plt
# 这两行代码解决中文标题乱码的问题
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
def open_csv(filename):
"""打开文件,返回读取的内容"""
f = open(filename, "r")
x = f.readlines()
f.close()
return x
def analyse(data):
"""对数据进行分组处理"""
sales = [] # y
dates = [] # x
for line in data:
date = line.strip().split(',')[0]
sale = eval(line.strip().split(',')[1]) # 要改为数字类型才能按顺序排列
dates.append(date)
sales.append(sale)
show_bar(dates, sales)
def show_bar(dates, sales):
plt.bar(dates, sales)
plt.legend()
# 设置图表标题,并给坐标轴添加标签
plt.title("每月销量条形图",
fontsize=20)
plt.xlabel("时间", fontsize=12)
plt.ylabel("销量", fontsize=12)
# 旋转坐标轴标签
plt.xticks(rotation=45)
plt.show()
if __name__ == '__main__':
filename = 'count_monthly_sales.csv'
data = open_csv(filename)
analyse(data)