获取天猫商品评论关键字及商品优缺点实例分析
实现功能:
- 获取天猫商品评论
- 针对评论内容:
- 给出评论关键词(同时通过自定义词典、去除停用词提高关键词的准确性)
- 区分正面评论和负面评论
- 给出商品评价建议
使用到的库:
- requests
- re
- jieba
- SnowNLP
python版本:2.7.10
获取商品评论
comments.py
# -*- coding:utf-8 -*-
import requests
import re
class TMALL:
def __init__(self,itemId):
self.default_url = 'https://rate.tmall.com/list_detail_rate.htm?itemId='+str(itemId)
self.sellerId = ''
self.itemId = itemId
self.commentsList = []
self.comments = []
self.pageNum = 1
self.file = None
#获取卖家id
def getSellerId(self,content):
parrern = re.compile(r'<input type="hidden" id="dsr-userid" value="(.*?)"/>')
result = re.search(parrern,content)
self.sellerId = result.group(1)
#获取商品详情
def getDetail(self):
r = requests.get('https://detail.tmall.com/item.htm?id='+str(self.itemId))
return r.text
#获取评论内容json串
def getPage(self,pageIndex):
if(self.sellerId!=''):
url = self.default_url+'&sellerId='+self.sellerId+'¤tPage='+str(pageIndex)
# print(url)
r = requests.get(self.default_url+'&sellerId='+self.sellerId+'¤tPage='+str(pageIndex))
return r.text
else:
print ("sellerId为空")
return
#获取评论总页数
def getPageNum(self,content):
parrern = re.compile(r'"lastPage":(.*?),"')
pagenum = re.search(parrern,content)
return pagenum.group(1)
#获取评论内容
def getComments(self,content):
parrern = re.compile(r'"rateContent":"(.*?)"')
comments = re.findall(parrern,content)
return comments
#保存评论到文件中
def save(self,comments):
f1 = open('comments.txt','w')
print u'正在写入文件...'
for comment in comments:
f1.write(comment.encode('utf-8'))
f1.write("\n")
print u'写入完成..'
f1.close()
#保存评论到commentsList变量和文件中,评论较多时,只取前5页评论内容
def saveComments(self):
detailContent = self.getDetail()
self.getSellerId(detailContent)
print(self.sellerId)
content = self.getPage(1)
self.pageNum = self.getPageNum(content)
print(self.pageNum)
if int(self.pageNum) >= 5:
self.pageNum = 5
# print(self.pageNum)
for pageIndex in range(1, int(self.pageNum)+1):
content = self.getPage(pageIndex)
self.comments = self.getComments(content)
self.commentsList += self.comments
self.save(self.commentsList)
return self.commentsList
# tmall = TMALL(556979556332)
# commentsList = tmall.saveComments()
- 评论请求获取
分析天猫商品详情页,可以看到评论内容是js单独返回的,那就可以通过请求https://rate.tmall.com/list_detail_rate.htm?itemId=557156077822&sellerId=1695308781¤tPage=1来获取评论内容(链接中有其他参数经验验证都不是必传的,这里就直接删除了) - 请求参数的确定
第一步请求中itemId由手动传入,sellerId则通过访问商品详情页可以获取到,pageNum在评论js文件中有返回,这样链接的参数变量都可以确定下来了 - 获取评论内容
用正则表达式就可以获取到所有的评论内容
parrern = re.compile(r'"rateContent":"(.*?)"')
comments = re.findall(parrern,content)
- 评论内容保存在文件和赋值给全局变量方便后续使用
评论分析
analysis.py
# -*- coding:utf-8 -*-
import jieba
import jieba.analyse
from snownlp import SnowNLP
import comments
class ANALYSIS:
def __init__(self,itemId):
tmall = comments.TMALL(itemId)
self.commentsList = tmall.saveComments()
self.prositiveCount = 0
self.negativeCount = 0
def getComments(self,filename):
f = open(filename)
comments = f.read()
f.close()
return comments
def getKeywords(self,comments):
jieba.load_userdict("dict.txt")
jieba.analyse.set_stop_words("stopwords.txt")
keywords = jieba.analyse.extract_tags(comments,topK=10,allowPOS=('a','av','al','x'))
#分词并保存
def cutComments(self):
jieba.load_userdict("dict.txt")
comments = self.getComments('comments.txt')
stopwords = {}.fromkeys([line.rstrip() for line in open('stopwords.txt')])
results = jieba.cut(comments,cut_all=False) #精确模式
# print ('/'.join(results))
final = []
for result in results:
# result = result.encode('utf-8')
if result not in stopwords:
final += result
# print (final)
self.saveToText('comments.txt',final)
#将正面评论和负面评论区分开,并保存到不同的文件中
def splitComments(self,comments):
# print comments
good = []
bad = []
for comment in comments:
if float(self.getSentiments(comment)) >= 0.5:
good.append(comment)
else:
bad.append(comment)
self.saveToText('goodcomments.txt', good)
print (u'goodcomments保存成功')
self.saveToText('badcomments.txt', bad)
print (u'badcomments保存成功')
#保存到文件
def saveToText(self,filename,comments):
f1 = open(filename, 'w')
print u'正在写入...'
for line in comments:
f1.write(line.encode('utf-8'))
f1.write('\n')
print u'写入完成..'
f1.close()
def getSentiments(self,comment):
return format(SnowNLP(comment).sentiments,'.15f')
def sentimentAnalysis(self):
for comment in self.commentsList:
# print(self.getSentiments(comment))
if float(self.getSentiments(comment)) >= 0.5:
self.prositiveCount += 1
else:
self.negativeCount +=1
print (self.prositiveCount)
print (self.negativeCount)
if self.prositiveCount >= self.negativeCount*2:
print ("这件商品评价很好哦")
elif self.prositiveCount < self.negativeCount:
print ("这件商品评价有点差哦")
else:
print ("这件商品评价一般般哦")
ana = ANALYSIS(557711363623)
cutcomments = ana.getComments('comments.txt')
ana.cutComments()
ana.sentimentAnalysis()
ana.getKeywords(cutcomments)
ana.splitComments(ana.commentsList)
goodcomments = ana.getComments('goodcomments.txt')
ana.getKeywords(goodcomments)
badcomments = ana.getComments('badcomments.txt')
ana.getKeywords(badcomments)
评论分析主要用到结巴分词及使用SnowNLP进行情感分析
获取关键词
def getKeywords(self,comments):
jieba.load_userdict("dict.txt")
# comments = self.getComments()
jieba.analyse.set_stop_words("stopwords.txt")
keywords = jieba.analyse.extract_tags(comments,topK=10,allowPOS=('a','av','al','x'))
# print(keywords)
print (','.join(keywords))
其中:
jieba.load_userdict("dict.txt")
表示加载自定义词典
添加自定义词典
结巴分词支持开发者使用自定义的词典,以便包含结巴词库里没有的词语。虽然结巴有新词识别能力,但自行添加新词可以保证更高的正确率,尤其是专有名词。
基本用法:jieba.load_userdict(file_name) #file_name为自定义词典的路径
词典格式和dict.txt一样,一个词占一行;每一行分三部分,一部分为词语,另一部分为词频,最后为词性(可省略,ns为地点名词),用空格隔开。
dict.txt内容截图如下:
![](https://img.haomeiwen.com/i30144/bdfd666536bd6c27.png)
jieba.analyse.set_stop_words("stopwords.txt")
设置自定义的停用词
停用词
在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词,这些字或词即被称为Stop Words(停用词)。
利用停用词对候选词进行过滤,去除无关紧要的词
基本用法:analyse.set_stop_words(file_name)#file_name为自定义停用词集合所在文件
文件内包含自定义的停用词,一个词占一行
keywords = jieba.analyse.extract_tags(comments,topK=10,allowPOS=('a','av','al','x'))
关键词提取
关键词提取
1.基于 TF-IDF 算法的关键词抽取
基本用法:jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=()) #需要先import jieba.analyse
setence:待提取的文本
topK:返回几个TF/IDF权重最大的关键词,默认值为20
withWeight:为是否一并返回关键词权重值,默认值为 False
allowPOS:仅包括指定词性的词,默认值为空,即不筛选
词性含义可参考:词性含义对照
2.关键词提取所使用逆向文件频率(IDF)文本语料库可以切换成自定义语料库的路径
用法: jieba.analyse.set_idf_path(file_name) # file_name为自定义语料库的路径
3.关键词提取所使用停止词(Stop Words)文本语料库可以切换成自定义语料库的路径
用法: jieba.analyse.set_stop_words(file_name) # file_name为自定义语料库的路径
4.基于 TextRank 算法的关键词抽取
jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 直接使用,接口相同,注意默认过滤词性。
jieba.analyse.TextRank() 新建自定义 TextRank 实例
分词
#分词并保存
def cutComments(self):
jieba.load_userdict("dict.txt")
comments = self.getComments('comments.txt')
stopwords = {}.fromkeys([line.rstrip() for line in open('stopwords.txt')])
results = jieba.cut(comments,cut_all=False) #精确模式
# print ('/'.join(results))
final = []
for result in results:
# result = result.encode('utf-8')
if result not in stopwords:
final += result
# print (final)
self.saveToText('comments.txt',final)
results = jieba.cut(comments,cut_all=False)
结巴分词的精确模式
结巴分词
jieba.cut分词有三种模式
精确模式:试图将句子最精确地切开,适合文本分析
用法:jieba.cut(text, cut_all=False)
全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义问题
用法:jieba.cut(str_text,cut_all=True)
搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
用法:jieba.cut_for_search(text)
默认是精确模式
用法:jieba.cut(str_text)
情感分析
def getSentiments(self,comment):
return format(SnowNLP(comment).sentiments,'.15f')
SnowNLP(comment).sentiments
情感分析
snowNLP
snowNLP支持中文分词、词性标注、情感分析(现在训练数据主要是买卖东西时的评价,所以对其他的一些可能效果不是很好,待解决、文本分类(Naive Bayes)、转换成拼音(Trie树实现的最大匹配)、繁体转简体(Trie树实现的最大匹配)、提取文本关键词(TextRank算法)、提取文本摘要TextRank算法)、tf,idf、Tokenization(分割成句子)、文本相似BM25等
这里主要来说情感分析的使用
用法:s = SnowNLP(text).sentiments#需要先from snownlp import SnowNLP
分析text的情感倾向,取值为(0,1),越靠近1,情感正向的概率越大
format(f,'.15f')
格式化函数
保留小数点后15位,如果不格式化,情感分析的结果可能会出现科学计数法的表达式
本篇主要介绍结巴分词和SnowNLP在实例中的应用,另外一些python常用库如requests、re等用法就不再详细说明。
附:
结巴分词官方文档:https://github.com/fxsjy/jieba
SnowNLP官方文档:https://github.com/isnowfy/snownlp