python_文本分析文本分析python热爱者

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

2017-12-20  本文已影响38人  威武不能屈

实现功能:

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

使用到的库:

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

上一篇 下一篇

猜你喜欢

热点阅读