day5-综合大作业写作分享
day5-综合大作业写作分享
作业要求说明
第一步:爱奇艺《青春有你2》评论数据爬取
(参考链接:https://www.iqiyi.com/v_19ryfkiv8w.html#curid=15068699100_9f9bab7e0d1e30c494622af777f4ba39)
- 爬取任意一期正片视频下评论
- 评论条数不少于1000条
第二步:词频统计并可视化展示
- 数据预处理:清理清洗评论中特殊字符(如:@#¥%、emoji表情符),清洗后结果存储为txt文档
中文分词:添加新增词(如:青你、奥利给、冲鸭),去除停用词(如:哦、因此、不然、也好、但是) - 统计top10高频词
- 可视化展示高频词
第三步:绘制词云
- 根据词频生成词云
- 可选项-添加背景图片,根据背景图片轮廓生成词云
第四步:结合PaddleHub,对评论进行内容审核
完成作业所需要的准备
- 中文分词需要jieba
- 词云绘制需要wordcloud
- 可视化展示中需要的中文字体
- 网上公开资源中找一个中文停用词表
- 根据分词结果自己制作新增词表
- 准备一张词云背景图(附加项,不做要求,可用hub抠图实现)
- paddlehub配置
完整代码展示及说明
# 安装jieba和词云,分别用于中文分词和词云绘制
!pip install jieba
!pip install wordcloud
#安装中文字体,可以本地上传,也可以在线安装
#如果是本地上传的话,需要注意上传的文件名和你所引用的文件名是否一致,
# 下载中文字体
#!wgethttps://mydueros.cdn.bcebos.com/font/simhei.ttf
# 查看系统可用的ttf格式中文字体
!fc-list :lang=zh | grep ".ttf"
# 创建系统字体文件路径
!mkdir .fonts
# 复制文件到该路径
!cp simhei.ttf .fonts/
#添加可视化所需要的字体
!rm -rf .cache/matplotlib
#字体的调用
from matplotlib.font_manager import _rebuild
_rebuild()
#安装模型,解析LSTM所用
!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 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
#"User-Agent": "Mozilla/5.0",
"Accept": "application/json",
"Referer": "http://m.iqiyi.com/v_19rqriflzg.html",
"Origin": "http://m.iqiyi.com",
"Host": "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",
"Accept-Encoding":"gzip, 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
'''
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:
#print(val.keys())
if 'content' in val.keys():
print(val['content'])
arr.append(val['content'])
lastId = str(val['id'])
return lastId
#使用正则去除文本中特殊字符,相关用法自行百度
def clear_special_char(content):
'''
正则处理特殊字符
参数 content:原文本
return: 清除后的文本
'''
s = re.sub(r"</?(.+?)>| |\t|\r", "",content)
s = re.compile('[a-zA-Z]')
s = re.compile('^\d+(\.\d+)?$')
s = re.compile('[^A-Z^a-z^0-9^\u4e00-\u9fa5]')
return s.sub('', content)
#对上面获取的评论进行分词
def fenci(text):
'''
利用jieba进行分词
参数 text:需要分词的句子或文本
return:分词结果
'''
#添加自定义字典,增加词库的内容,可以使分词的效果更好
jieba.load_userdict('add_words.txt')
seg = jieba.lcut(text, cut_all=False)
return seg
#中文停用词的使用,对文本进行优化。所需要的文件可以百度下载
def stopwordslist(file_path):
'''
创建停用词表
参数 file_path:停用词文本路径
return:停用词list
'''
stopwords = [line.strip() for line in open(file_path, encoding='UTF-8').readline()]
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 #j解决保存图像是负号‘-’显示为方块的问题
plt.bar(x_aixs,y_aixs)
plt.title('词频统计结果')
plt.show()
#根据词频统计来绘制词云
import jieba # 分词
from wordcloud import WordCloud # 词云图
import matplotlib.colors as colors # 处理图片相关内容
import numpy
from PIL import Image
import matplotlib.pyplot as plt
def drawcloud(word_f):
'''
根据词频绘制词云图
参数 word_f:统计出的词频结果
return:none
'''
with open(r'aqy.txt', 'r', encoding='utf-8') as txt:
data = txt.read()
words_list = jieba.lcut(data)
# 用空格分隔词语
tokenstr = ' '.join(words_list)
cloud_mask=np.array(Image.open('map.png'))
st=set(['东西', '这是'])
# 自定义文字颜色
colormaps = colors.ListedColormap(['#FF0000','#FF7F50','#FFE4C4'])
wc=WordCloud(background_color='white',
mask=cloud_mask,
max_words=250,
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)
plt.axis('off')
plt.show()
wc.to_file('pic.png') # 生成词云图片
def text_detection(text,file_path):
'''
使用hub对评论进行内容分析
return:分析结果
'''
porn_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 = porn_detection_lstm.detection(data=input_dict,use_gpu=False, batch_size=1)
# print(results)
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=120
lastId='0'
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 e:
print('含有特殊字符')
print("共获取评论:", len(arr))
f=open('aqy.txt', 'r', encoding='utf-8')
counts={}
for line in f:
words=fenci(line)
stopwords=stopwordslist(r'./stopwords/中文停用词表.txt')
movestopwords(words, stopwords, counts)
drawcounts(counts, 10)
drawcloud(counts)
f.close()
file_path='aqy.txt'
test_text=[]
text_detection(test_text, file_path)
display(Image.open('pic.png')) #显示生成的词云图像
最终结果展示
所用到的文件
可能遇到的问题(重点)
- 文字乱码
原因是因为上传的字体没安装,解决办法见上面代码部分。
-
上传了图片,但是词云显示任然是矩形
类似这样:
解决办法:词云用的图四面都不能挨边,就是说四边都要是底色,所以你上传的图片无论内容是啥,但背景必须是白底的。可以参考上面的代码。 -
TypeError: getMovieinfo() takes 0 positional arguments but 1 was given
解决办法:getMovieinfo()这个函数的参数没有加进去,你查看下这个函数的源代码。
4.文本格式问题
解决办法:将文本TXT格式改成UTF-8
- 获取评论数量太少的问题
可能有人这里获得的评论数量只有199,但作业要求是1000条以上,所以我们需要做的是检查一下代码。
适当增大这里的num值。
好了,问题就先写到这里了,当然,代码的思想可能相同,但出现的bug千千万万,出现了问题大家还是要多查查资料,多问问大神,代码写的多了,bug自然就少了!哈哈!!!
人生苦短,我选python!
day5的分析就先写到这里了!下次再写心得和day4和比赛项目的分享,谢谢!