#导入requests库(请求和页面抓取) import requests #导入time库(设置抓取Sleep时间) import time #导入random库(生成乱序随机数) import random #导入正则库(从页面代码中提取信息) import re #导入数值计算库(常规计算) import numpy as np #导入科学计算库(拼表及各种分析汇总) import pandas as pd #导入绘制图表库(数据可视化) import matplotlib.pyplot as plt #导入结巴分词库(分词) import jieba as jb #导入结巴分词(关键词提取) import jieba.analyse
#设置请求中头文件的信息
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept':'text/html;q=0.9,*/*;q=0.8',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Connection':'close',
'Referer':'https://www.jd.com/'
}
#设置Cookie的内容
cookie={'TrackID':'1_VWwvLYiy1FUr7wSr6HHmHhadG8d1-Qv-TVaw8JwcFG4EksqyLyx1SO7O06_Y_XUCyQMksp3RVb2ezA',
'__jda':'122270672.1507607632.1423495705.1479785414.1479794553.92',
'__jdb':'122270672.1.1507607632|92.1479794553',
'__jdc':'122270672',
'__jdu':'1507607632',
'__jdv':'122270672|direct|-|none|-|1478747025001',
'areaId':'1',
'cn':'0',
'ipLoc-djd':'1-72-2799-0',
'ipLocation':'%u5317%u4EAC',
'mx':'0_X',
'rkv':'V0800',
'user-key':'216123d5-4ed3-47b0-9289-12345',
'xtest':'4657.553.d9798cdf31c02d86b8b81cc119d94836.b7a782741f667201b54880c925faec4b'}
#设置URL的第一部分 url1='https://sclub.jd.com/comment/productPageComments.action?productId=10001234327&score=0&sortType=3&page=' #设置URL的第二部分 url2='&pageSize=10&callback=fetchJSON_comment98vv41127' #乱序输出0-80的唯一随机数 ran_num=random.sample(range(80), 80)
#拼接URL并乱序循环抓取页面
for i in ran_num:
a = ran_num[0]
if i == a:
i=str(i)
url=(url1+i+url2)
r=requests.get(url=url,headers=headers,cookies=cookie)
html=r.content
else:
i=str(i)
url=(url1+i+url2)
r=requests.get(url=url,headers=headers,cookies=cookie)
html2=r.content
html = html + html2
time.sleep(5)
print("当前抓取页面:",url,"状态:",r)
#对抓取的页面进行编码 html=str(html, encoding = "GBK")
#将编码后的页面输出为txt文本存储
file = open("c:\\Users \\Desktop\\page.txt", "w")
file.write(html)
file.close()
#读取存储的txt文本文件
html = open('c:\\Users\\ Desktop\\page.txt', 'r').read()
#使用正则提取userClient字段信息 userClient=re.findall(r',"usefulVoteCount".*?,"userClientShow":(.*?),',html) #使用正则提取userLevel字段信息 userLevel=re.findall(r'"referenceImage".*?,"userLevelName":(.*?),',html) #使用正则提取productColor字段信息 productColor=re.findall(r'"creationTime".*?,"productColor":(.*?),',html) #使用正则提取recommend字段信息 recommend=re.findall(r'"creationTime".*?,"recommend":(.*?),',html) #使用正则提取nickname字段信息 nickname=re.findall(r'"creationTime".*?,"nickname":(.*?),',html) #使用正则提取userProvince字段信息 userProvince=re.findall(r'"referenceImage".*?,"userProvince":(.*?),',html) #使用正则提取usefulVoteCount字段信息 usefulVoteCount=re.findall(r'"referenceImage".*?,"usefulVoteCount":(.*?),',html) #使用正则提取days字段信息 days=re.findall(r'"usefulVoteCount".*?,"days":(.*?)}',html) #使用正则提取score字段信息 score=re.findall(r'"referenceImage".*?,"score":(.*?),',html)</pre>
还有一些字段比较负责,无法通过正则一次提取出来,比如isMobile字段,有些值的后面还有大括号。这就需要进一步的提取和清洗工作。
#使用正则提取isMobile字段信息 isMobile=re.findall(r'"usefulVoteCount".*?,"isMobile":(.*?),',html)
#替换掉最后的}
mobile=[]
for m in isMobile:
n=m.replace('}','')
mobile.append(n)
#使用正则提取productSize字段信息 productSize=re.findall(r'"creationTime".*?,"productSize":(.*?),',html)
#提取杯罩信息 cup=[] for s in productSize: s1=s[3] cup.append(s1)
#使用正则提取时间字段信息 creationTime1=re.findall(r'"creationTime":(.*?),"referenceName',html)
#提取日期和时间 creationTime=[] for d in creationTime1: date=d[1:20] creationTime.append(date)
#提取小时信息 hour=[] for h in creationTime: date=h[10:13] hour.append(date)
#使用正则提取评论信息 content=re.findall(r'"guid".*?,"content":(.*?),',html)
#对提取的评论信息进行去重 content_1=[] for i in content: if not "img" in i: content_1.append(i)
#将前面提取的各字段信息汇总为table数据表,以便后面分析
table=pd.DataFrame({'creationTime':creationTime,'hour':hour,'nickname':nickname,'productColor':productColor,'productSize':productSize,'cup':cup,'recommend':recommend,'mobile':mobile,'userClient':userClient,'userLevel':userLevel,'userProvince':userProvince,'usefulVoteCount':usefulVoteCount,'content_1':content_1,'days':days,'score':score})
#将creationTime字段更改为时间格式
table['creationTime']=pd.to_datetime(table['creationTime'])
#设置creationTime字段为索引列
table = table.set_index('creationTime')
#设置days字段为数值格式
table['days']=table['days'].astype(np.int64)
#查看整理完的数据表
table.head()
#保存table数据表
table.to_csv('jd_table.csv')
#对数据表按月进行汇总并生成新的月度汇总数据表
table_month=table.resample('M',how=len)
#提取按月汇总的nickname
month=table_month['nickname']
#绘制分月评论数量变化趋势图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13])
plt.bar([1,2,3,4,5,6,7,8,9,10,11,12,13],month,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('月份')
plt.ylabel('评论数量')
plt.title('分月评论数量变化趋势')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('15-11','12','16-01','02','03','04','05','06','07','08','09','10','11'))
plt.show()
#在table表中筛选使用移动设备的条目并创建新表
mobile_t=table.loc[table["mobile"] == "true"]
#在table中筛选没有使用移动设备的条目并创建新表
mobile_f=table.loc[table["mobile"] == "false"]
#按月汇总使用移动设备的数据
mobile_t_m=mobile_t.resample('M',how=len)
#按月汇总不使用移动设备的数据
mobile_f_m=mobile_f.resample('M',how=len)
#提取使用移动设备的按月汇总nickname
mobile_y=mobile_t_m['nickname']
#提取没有使用移动设备的按月汇总nickname
mobile_n=mobile_f_m['nickname']
#绘制PC与移动设备评论数量变化趋势图
plt.subplot(2, 1, 1)
plt.plot(mobile_y,'go',mobile_y,'g-',color='#99CC01',linewidth=3,markeredgewidth=3,markeredgecolor='#99CC01',alpha=0.8)
plt.ylabel('移动设备评论数量')
plt.title('PC与移动设备评论数量变化趋势')
plt.subplot(2, 1, 2)
plt.plot(mobile_n,'go',mobile_n,'g-',color='#99CC01',linewidth=3,markeredgewidth=3,markeredgecolor='#99CC01',alpha=0.8)
plt.xlabel('月份')
plt.ylabel('PC评论数量')
plt.show()
#按24小时分别对table表中的nickname进行计数
hour_group=table.groupby('hour')['nickname'].agg(len)
#汇总24小时评论数量变化趋势图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23])
plt.bar([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],hour_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('24小时')
plt.ylabel('评论数量')
plt.title('24小时评论数量变化趋势')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('0','1','2','3','4','5','6','7','8','9','10','11','12''13','14','15','16','17','18','19','20','21','22','23'))
plt.show()
#在使用移动设备的表中按24小时对nickname进行计数
mobile_y_h=mobile_t.groupby('hour')['nickname'].agg(len)
#在没有使用移动设备的表中按24小时对nickname进行计算
mobile_n_h=mobile_f.groupby('hour')['nickname'].agg(len)
#汇总PC与移动设备24小时评论数量变化趋势
plt.subplot(2, 1, 1)
plt.plot(mobile_y_h,'go',mobile_y_h,'g-',color='#99CC01',linewidth=3,markeredgewidth=3,markeredgecolor='#99CC01',alpha=0.8)
plt.ylabel('移动设备评论数量')
plt.title('PC与移动设备24小时评论数量变化趋势')
plt.subplot(2, 1, 2)
plt.plot(mobile_n_h,'go',mobile_n_h,'g-',color='#99CC01',linewidth=3,markeredgewidth=3,markeredgecolor='#99CC01',alpha=0.8)
plt.xlabel('24小时')
plt.ylabel('PC评论数量')
plt.show()
[img]http://files.jb51.net/file_images/article/201612/2016121608313920.png[/img]
用户客户端分布情况
前面的分析中,我们看到使用移动设备进行评论的用户要远高于PC端的用户,下面我们对用户所使用的设备分布情况进行统计。首先在数据表中按用户设备(userClient)对nickname字段进行计数汇总。
#在table表中按userClient对数据进行汇总
userClient_group=table.groupby('userClient')['nickname'].agg(len)
#汇总用户客户端分布情况
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5,6])
plt.bar([1,2,3,4,5,6],userClient_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('客户端分布')
plt.ylabel('评论数量')
plt.title('用户客户端分布情况')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.ylim(0,300)
plt.xticks(a,('PC','Android','iPad','iPhone','微信购物','QQ购物'))
plt.show()
#设置分组条件,并对table表中的days字段进行分组
bins = [0, 5, 10, 15, 20, 25, 30, 92]
day_group = ['5天', '10天', '15天', '20天', '25天','30天','大于30天']
table['day_group'] = pd.cut(table['days'], bins, labels=day_group)
#按新设置的分组对数据进行汇总
days_group=table.groupby('day_group')['nickname'].agg(len)
#绘制用户购买后评论天数分布图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5,6,7])
plt.bar([1,2,3,4,5,6,7],days_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('购买后天数')
plt.ylabel('发布评论数量')
plt.title('购买后评论天数分布')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.ylim(0,300)
plt.xticks(a,('5天','10天','15天','20天','25天','30天','大于30天'))
plt.show()
#在table表中按score对数据进行汇总
score_group=table.groupby('score')['nickname'].agg(len)
#绘制用户评分分布情况图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5])
plt.bar([1,2,3,4,5],score_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('评分分布')
plt.ylabel('评论数量')
plt.title('用户评分分布情况')
plt.legend(['评论数量'], loc='best')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.ylim(0,700)
plt.xticks(a,('1星','2星','3星','4星','5星'))
plt.show()
#在table 表中按cup对数据进行汇总
cup_group=table.groupby('cup')['nickname'].agg(len)
#绘制用户胸罩尺码分布图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4])
plt.bar([1,2,3,4],cup_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('尺码')
plt.ylabel('评论数量')
plt.title('用户胸罩尺码分布情况')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.ylim(0,350)
plt.xticks(a,('B','C','D','E'))
plt.show()
#在table表中按productColor对数据进行汇总
color_group=table.groupby('productColor')['nickname'].agg(len)
#绘制用户颜色选择分布图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3])
plt.bar([1,2,3],color_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('颜色分布')
plt.ylabel('评论数量')
plt.title('用户颜色选择分布')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.ylim(0,600)
plt.xticks(a,('红色','肤色','黑色'))
plt.show()
#使用数据透视表对胸罩尺码和颜色进行交叉分析 color_size=pd.pivot_table(table,index=["cup"],values=["nickname"],columns=["productColor"],aggfunc=len,fill_value=0)
#提取B,C,D,E尺码的颜色分布 b=color_size.ix['B'] c=color_size.ix['C'] d=color_size.ix['D'] e=color_size.ix['E']
#汇总不同胸罩尺码颜色分布图
plt.rc('font', family='STXihei', size=9)
plt.subplot(2, 2, 1)
plt.bar([1,2,3],b,color=["#EE9788","#E2D4C9","#151419"],alpha=0.8,align='center',edgecolor='white')
plt.title('B Cup')
plt.xticks(a,('红色','肤色','黑色'))
plt.subplot(2, 2, 2)
plt.bar([1,2,3],c,color=["#EE9788","#E2D4C9","#151419"],alpha=0.8,align='center',edgecolor='white')
plt.title('C Cup')
plt.ylim(0,200)
plt.xticks(a,('红色','肤色','黑色'))
plt.subplot(2, 2, 3)
plt.bar([1,2,3],d,color=["#EE9788","#E2D4C9","#151419"],alpha=0.8,align='center',edgecolor='white')
plt.title('D Cup')
plt.xticks(a,('红色','肤色','黑色'))
plt.subplot(2, 2, 4)
plt.bar([1,2,3],e,color=["#EE9788","#E2D4C9","#151419"],alpha=0.8,align='center',edgecolor='white')
plt.title('E,Cup')
plt.xticks(a,('红色','肤色','黑色'))
plt.show()
#从table表中提取cup尺寸为D或E的数据条目并创建新表 table_big=table.loc[(table["cup"] == "D")|(table["cup"] == "E")]
#按城市对数据进行计数汇总
city_group=table_big.groupby('userProvince')['nickname'].agg(len)
#汇总D和E Cup城市分布图
plt.rc('font', family='STXihei', size=9)
a=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
plt.barh([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],city_group,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('评论数量')
plt.ylabel('城市')
plt.title('D Cup和E Cup城市分布')
plt.legend(['评论数量'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='x',alpha=0.4)
plt.yticks(a,('未知','上海','云南','内蒙古','北京','四川','天津','宁夏','安徽','山东','广东','江西','江苏','江西','河北','河南','浙江','湖北','湖南','甘肃','福建','辽宁','重庆','青海','香港'))
plt.show()
#筛选包含”老婆”和”女朋友”的评论 content_2=[] for i in content_1: if "老婆"in i or "女朋友"in i: content_2.append(i)
#查看评论内容 content_2
#计算老公或男朋友购买胸罩的比例 len(content_2)/len(content_1)*100 2.3545706371191137
#文本数据格式转换
word_str = ''.join(content_1)
#提取文字关键词
word_rank=jieba.analyse.extract_tags(word_str, topK=20, withWeight=True, allowPOS=())
#转化为数据表
word_rank = pd.DataFrame(word_rank,columns=['word','rank'])
#查看关键词及权重
word_rank.sort('rank',ascending=False)
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有