美文网首页python_文本分析文本分析python热爱者
获取天猫商品评论关键字及商品优缺点实例分析

获取天猫商品评论关键字及商品优缺点实例分析

作者: 威武不能屈 | 来源:发表于2017-12-20 19:51 被阅读38次

    实现功能:

    1. 获取天猫商品评论
    2. 针对评论内容:
      • 给出评论关键词(同时通过自定义词典、去除停用词提高关键词的准确性)
      • 区分正面评论和负面评论
      • 给出商品评价建议

    使用到的库:

    • 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+'&currentPage='+str(pageIndex)
                # print(url)
                r = requests.get(self.default_url+'&sellerId='+self.sellerId+'&currentPage='+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()
    
    1. 评论请求获取
      分析天猫商品详情页,可以看到评论内容是js单独返回的,那就可以通过请求https://rate.tmall.com/list_detail_rate.htm?itemId=557156077822&sellerId=1695308781&currentPage=1来获取评论内容(链接中有其他参数经验验证都不是必传的,这里就直接删除了)
    2. 请求参数的确定
      第一步请求中itemId由手动传入,sellerId则通过访问商品详情页可以获取到,pageNum在评论js文件中有返回,这样链接的参数变量都可以确定下来了
    3. 获取评论内容
      用正则表达式就可以获取到所有的评论内容
      parrern = re.compile(r'"rateContent":"(.*?)"')
            comments = re.findall(parrern,content)
    
    1. 评论内容保存在文件和赋值给全局变量方便后续使用

    评论分析

    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内容截图如下:


    图1

    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

    相关文章

      网友评论

        本文标题:获取天猫商品评论关键字及商品优缺点实例分析

        本文链接:https://www.haomeiwen.com/subject/utwbwxtx.html