Python小白逆袭大神(飞桨七天课程)---Day5-综合大作业
参加了百度的python七天课程: https://aistudio.baidu.com/aistudio/index
分享一下最后的大作业:
(ps:写作业过程中碰到了add_words问题,参考了叁岁大佬的这篇博文https://blog.csdn.net/weixin_45623093/article/details/105794512)
综合大作业
**第一步:**爱奇艺《青春有你2》评论数据爬取(参考链接:https://www.iqiyi.com/v_19ryfkiv8w.html#curid=15068699100_9f9bab7e0d1e30c494622af777f4ba39)
爬取任意一期正片视频下评论
评论条数不少于1000条
**第二步:**词频统计并可视化展示
数据预处理:清理清洗评论中特殊字符(如:@#¥%、emoji表情符),清洗后结果存储为txt文档
中文分词:添加新增词(如:青你、奥利给、冲鸭),去除停用词(如:哦、因此、不然、也好、但是)
统计top10高频词
可视化展示高频词
**第三步:**绘制词云
根据词频生成词云
可选项-添加背景图片,根据背景图片轮廓生成词云
**第四步:**结合PaddleHub,对评论进行内容审核
需要的配置和准备
中文分词需要jieba
词云绘制需要wordcloud
可视化展示中需要的中文字体
网上公开资源中找一个中文停用词表
根据分词结果自己制作新增词表
准备一张词云背景图(附加项,不做要求,可用hub抠图实现)
paddlehub配置
!pip install jieba !pip install wordcloud
# Linux系统默认字体文件路径 # !ls /usr/share/fonts/ # 查看系统可用的ttf格式中文字体 !fc-list :lang=zh | grep ".ttf"
# 下载中文字体 !wget https://mydueros.cdn.bcebos.com/font/simhei.ttf # 将字体文件复制到matplotlib字体路径 !cp simhei.ttf /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/ # 一般只需要将字体文件复制到系统字体目录下即可,但是在aistudio上该路径没有写权限,所以此方法不能用 # !cp simhei.ttf /usr/share/fonts/ # 创建系统字体文件路径 #!mkdir .fonts # 复制文件到该路径 !cp simhei.ttf .fonts/ !rm -rf .cache/matplotlib
这里的simhei.ttf需要自己在网上下载,然后上传到当前工作路径下。
#安装模型 !hub install porn_detection_lstm==1.1.0 !pip install --upgrade paddlehub
from __future__ import print_function import requests import json import re #正则匹配 import time #时间处理模块 import jieba #中文分词 import numpy as np import matplotlib import matplotlib.pyplot as plt import matplotlib.font_manager as font_manager from PIL import Image from wordcloud import WordCloud #绘制词云模块 import paddlehub as hub
#请求爱奇艺评论接口,返回response信息 def getMovieinfo(url): # ''' # 请求爱奇艺评论接口,返回response信息 # 参数 url: 评论的url # :return: response信息 # ''' session = requests.Session() headers = { "User-Agent":"Mozilla/5.0", "Accept":"application/json", "Refer":"http://m.iqiyi.com/v_19rqriflzg.html", "Origin":"http://m.iqiyi.com", "Bost":"sns-comment.iqiyi.com", "Connection":"keep-alive", "Accept-Language":"en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6", "Aceept-Encoding":"qzip,deflate" } response = session.get(url, headers=headers) if response.status_code == 200: return response.text return None #解析json数据,获取评论 def saveMovieInfoToFile(lastId,arr): # ''' # 解析json数据,获取评论 # 参数 lastId:最后一条评论ID arr:存放文本的list # :return: 新的lastId # ''' url = "http://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&\agent_version=9.11.5&business_type=17&content_id=15068699100&page_size=10&type=time&last_id=" #url='https://sns-comment.iqiyi.com/v3/comment/get_comments.action?agent_type=118&agent_version=9.11.5&authcookie=null&business_type=17&content_id=15068699100&page=&page_size=10&types=time&last_id=' url += str(lastId) responseTxt = getMovieinfo(url) responseJson = json.loads(responseTxt) comments = responseJson['data']['comments'] for val in comments: if 'content' in val.keys(): print(val['content']) arr.append(val['content']) lastId = str(val['id']) return lastId
注意上面这部分一定要认真检查一下headers和url等的正确性,因为在这里打错是不会报错的,但是之后主函数调用运行的时候会无法爬取评论。之前不小心多打了一个字母,debug了很久才发现是这里的问题(可能是我比较粗心)。
#去除文本中特殊字符 def clear_special_char(content): ''' 正则处理特殊字符 参数 content:原文本 return: 清除后的文本 ''' # s = re.sub(r"</?(.+?)>| |\t|\r","",content) # s = re.sub(r"\n","",s) # s = re.sub(r"\*","\\*",s) # s = re.sub('[^\u4e00-\u9fa5^a-z^A-Z^0-9]',"",s) # s = re.sub('[\001\002\003\004\005\006\007\x08\x09\x0a\x0b\x0c\x0d\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d]','',s) # s = re.sub('[a-zA-Z]','',s) # s = re.sub('^\d+(\.\d+)?$','',s) s = re.sub(r"</?(.+?)>| |\t|\r", "", content) s =re.sub(r"\n", "", s) s =re.sub(r"\*", "\\*", s) s =re.sub("\u4e00-\u9fa5^a-z^A-Z^0-9", "", s) s = re.sub( '[\001\002\003\004\005\006\007\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a]+', '', s) s = re.sub('[a-zA-Z]', "", s) s = re.sub('^\d+(\.\d+)?$', "", s) s = re.sub(u'[\U00010000-\U0010ffff]', ' ',s) s = re.sub(u'[\uD800-\uDBFF][\uDC00-\uDFFF]', ' ', s) for ch in ',。;:“”、》《、|*&…🙏!♥♡😊🌚?💚√🍼【】💔🐴]๑👍[🌟😘🤘ノ🐱👩❤“💎🌸💙😁❄,≧▽≦👀🐶🍬😂 !🧡😃 ヾ↗~↖^ 🏻🍋~♀٩௰^ و˃͈ ̶ω˂😆௰ ˂🔒🧍💛💚💖Ő ∀Ő∀✔🤠( ง _ • 。́ ) ง🔒✨🍑💙💜👧🐛🐟✊🌠🌨💪⭐”…': s = s.replace(ch, ' ') return s
上面这段主要是通过正则的方法清除掉爬取的评论中的无用部分。
ps:清除emoji的思路来自同营大佬,这里可以在运行出来之后,看看乱码里面有哪些emoji,然后对应着在这里清除掉。其他无效字符也是同理。
def fenci(text): ''' 利用jieba进行分词 参数 text:需要分词的句子或文本 return:分词结果 ''' jieba.load_userdict('add_words.txt') seg = jieba.lcut(text,cut_all=False) return seg
注意,上面的分词文档add_words需要自己自己编写,主要是加入评论中可能出现的高频词,如人气选手姓名等等(可以爬出来评论之后看一下都有哪些高频词,自己手动加一下,毕竟机器模型识别不出来一些人名),注意在加入时每个高频词单独占一行(估计是参数读取方式是按‘\n’读入的原因)。
def stopwordslist(file_path): ''' 创建停用词表 参数 file_path:停用词文本路径 return:停用词list ''' stopwords = [line.strip() for line in open(file_path, encoding='UTF-8').readlines()] return stopwords
def movestopwords(sentence,stopwords,counts): ''' 去除停用词,统计词频 参数 file_path:停用词文本路径 stopwords:停用词list counts: 词频统计结果 return:None ''' out = [] for word in sentence: if word not in stopwords: if len(word) !=1: counts[word] = counts.get(word,0) + 1 return None
def drawcounts(counts,num): ''' 绘制词频统计表 参数 counts: 词频统计结果 num:绘制topN return:none ''' x_aixs = [] y_aixs = [] c_order = sorted(counts.items(), key = lambda x:x[1],reverse=True) for c in c_order[:num]: x_aixs.append(c[0]) y_aixs.append(c[1]) #设置显示中文 matplotlib.rcParams['font.sans-serif'] = ['simHei']#指定默认字体 matplotlib.rcParams['axes.unicode_minus'] = False plt.bar(x_aixs, y_aixs) plt.title('词频统计结果') plt.show()
def drawcloud(word_f): ''' 根据词频绘制词云图 参数 word_f:统计出的词频结果 return:none ''' #加载背景图片 cloud_mask = np.array(Image.open('cloud3.png')) #忽略显示的词 st=set(["东西","这是"]) #生成wordcloud对象 wc = WordCloud(background_color='white', mask = cloud_mask, max_words=150, font_path='simhei.ttf', min_font_size=10, max_font_size=100, width=400, relative_scaling=0.3, stopwords=st) wc.fit_words(word_f) wc.to_file('pic.png')
这里的cloud.png是一个透明底的背景图,后面词云会根据cloud图里的形状生成,需要自己添加,我是自己p的。
def text_detection(text,file_path): ''' 使用hub对评论进行内容分析 return:分析结果 ''' pron_detection_lstm = hub.Module(name='porn_detection_lstm') f = open('aqy.txt','r',encoding='utf-8') for line in f: if len(line.strip())==1: continue else: test_text.append(line) f.close() input_dict = {"text":test_text} results = pron_detection_lstm.detection(data=input_dict,use_gpu=False, batch_size=1) for index,item in enumerate(results): if item['porn_detection_key'] == 'porn': print(item['text'],':',item['porn_probs'])
#评论是多分页的,得多次请求爱奇艺的评论接口才能获取多页评论,有些评论含有表情、特殊字符之类的 #num 是页数,一页10条评论,假如爬取1000条评论,设置num=100 if __name__ == "__main__": num = 200 lastId = '0' #lastId是接口分页id arr = []#爬取的所有评论存放的数组 with open('aqy.txt','a',encoding='utf-8') as f: for i in range(num): lastId = saveMovieInfoToFile(lastId,arr) time.sleep(0.5) for item in arr: Item = clear_special_char(item) if Item.strip()!='': try: f.write(Item+'\n') except Exception as e: print("含有特殊字符") print('共爬取评论:',len(arr)) f = open('aqy.txt','r',encoding='utf-8') counts = {} for line in f: words = fenci(line) #stopwords = stopwordslist('cn_stopwords.txt') stopwords = stopwordslist(r'中文停用词表.txt') movestopwords(words,stopwords,counts) drawcounts(counts,10)#绘制前十名高频词 drawcloud(counts)#绘制词云 f.close() #使用hub对评论进行内容分析 file_path = 'aqy.txt' test_text = [] text_detection(test_text,file_path)
这部分就是主函数了,运行之后可以看到自己爬取的评论内容、数量、还有top10的热词词频图等。下面放一下我运行结果的部分截图。
最后是打印一下词云图片。
display(Image.open('pic.png')) #显示生成的词云图像syuichihann 原创文章 2获赞 0访问量 122 关注 私信
- Python小白逆袭大神课程-Day1作业
- Python小白逆袭大神:百度飞桨课程结营心得
- 百度python小白逆袭大神系列课程day5——爱奇艺《青你2》评论爬取并分析
- AI studio 训练分享之Python小白逆袭大神课程
- 百度飞桨-Python小白逆袭大神-结营心得
- 百度飞桨——python小白逆袭大神 结营心得
- 飞桨Python小白逆袭大神心得
- 【百度训练营】python小白逆袭大神 day5心得
- Python小白逆袭大神课程-Day1内容
- PaddlePaddle飞桨Python小白逆袭大神打卡营记录
- 百度python小白逆袭大神系列课程day4——paddlehub之《青春有你2》五人识别
- 百度飞桨-python小白逆袭大神7天打卡营-完结心得-Rick
- 百度飞桨Python小白逆袭大神7天打卡-心得
- 百度飞浆Python小白逆袭大神打卡课程心得分享-《青春有你2》选手信息爬取
- 参与飞桨--百度python小白逆袭大神的学习心得--paddlehub
- 【百度训练营】python小白逆袭大神 day4心得
- 【百度训练营】python小白逆袭大神 day3心得
- 【百度训练营】python小白逆袭大神 day2心得
- 【百度训练营】python小白逆袭大神 day1心得
- Python小白逆袭大神:Day3-人工智能常用Python库+数据分析