最近宫斗剧《延禧攻略》大火,大家称赞的原因除了剧情,演员的演技之外,还有精良的制作,甚至有人给出了高颜值的历史教科书的评价,初次之外,某些反派角色的饰演者的微博更是被“正义”的观众给攻陷了。本文将通过爬取评论区的评论,来看看小伙伴都在热议啥。
本文分两大部分,第一部分是爬虫部分,爬取评论区信息;第二部分对数据进行分析。
爬虫部分
前期分析
这里我们选取豆瓣上的评论作为目标,与一般的爬虫无异,首先是分析网站信息,分析的方法与之前的爬虫例子一样:广西某211高校新闻爬取,城市空气质量爬取。
经过分析,发现评论区每个页面存放20条评论,每条评论有一个单独的页面,因此采取的方法位逐一获取每个页面的评论列表,提取每条评论的链接,再获取其评论内容。这里我们选择爬取前150页的评论信息。
经过以上分析,可以确定程序需要做的工作如下:从第1页到第150页逐一获取评论列表,接着逐一获取每条评论的文本内容。因逐一获取评论列表内容较多,因此考虑采取多线程的爬取方式,每30页为一个线程进行爬取。
代码编写
小编在此谢谢大家的观看!Python很容易学!所以小编有弄一个交流,互问互答,资源共享的交流学习基地,如果你也是Python的学习者或者大牛都欢迎你来!㪊:548+377+875!一起 学习共同进步!
接着开始编写代码的基本框架,首先需要有一个向页面发起请求的函数;接着需要有解析评论列表页面的函数,用来获取每个评论的链接;对于每一个评论页面,也需要进行解析;对于获取到的评论内容,需要进行保存。因此,整个函数的基本结构应该如下:
get_html()函数用于需要发起url请求获取信息,这里用到requests库的get方法:
def get_html(url):
# 构造请求头
headers = {'User-Agent':'Mozilla/5.0'}
# 随机暂停
t = random.randint(2,15)
print('暂停{}s'.format(t))
time.sleep(t)
# 发起请求获取html
r = requests.get(url,headers=headers)
html = r.text
return html
我们首先需要获取的是评论列表的页面,先获取每条评论的链接才能获取评论内容。因此,我们使用parser_page_list()函数解析评论列表页面的信息,使用parser_per_comment()函数解析每条评论的信息:
# 解析每条评论的网页,获取评论内容
def parser_per_commet(html,from_page,end_page):
# 保存每一个评论页面的评论标题以及内容
soup = BeautifulSoup(html,'html.parser')
title = soup.find('div',{'id':'content'}).find('h1').text.strip()
p = soup.find('div',{'id':'link-report'}).find('span',{'class':''}).find_all('p')
content = ''
for i in range(len(p)):
content += p[i].text.strip()
save_file(title,content,from_page,end_page)
# 解析每个评论列表页面,获取每条评论的链接
def parser_page_list(html,from_page,end_page):
# 获取每个评论列表页面的href链接
soup = BeautifulSoup(html,'html.parser')
tr = soup.find('table',{'class':'olt'}).find_all('tr')
hrefs = []
for i in range(1,len(tr)):
href = tr[i].find('a').get('href')
hrefs.append(href)
# print(hrefs)
for href in hrefs:
try:
# 每隔若干秒开始爬取评论的标题和内容
time.sleep(random.randint(3,15))
html = get_html(href)
parser_per_commet(html,from_page,end_page)
except:
continue
由于加了延时爬取,单线程爬取150个页面的评论会变慢,除此之外,由于一个IP地址频繁的访问网站,很容易会出发网站的反爬机制。因此,加入了多线程,每个线程爬取30页的评论内容:
# 每条线程的开始页面以及结束页面
def from_to_thread(from_page,end_page):
for i in range(from_page,end_page):
yx_dicussion_url = 'https://movie.douban.com/subject/26999852/discussion/?start={}&sort_by=time'.format(i*20)
time.sleep(random.randint(5,20))
html = get_html(yx_dicussion_url)
parser_page_list(html,from_page,end_page)
if __name__ == '__main__':
for i in range(0,150,30):
from_to_ = threading.Thread(target=from_to_thread,args=(i,i+29))
from_to_.start()
最后的文件保存,为避免多线程之间读写同一变量造成不可预知的错误,因此保存文件时,采取了一个线程对应保存一个文件的方式:
# 保存评论内容
def save_file(title,content,from_page,end_page):
with open('yxgl_{}_{}.txt'.format(from_page,end_page),'a',encoding='utf-8') as f:
f.write(title + '' + content + '')
分析统计
词云分析
对于文本内容的分析,采取词云的方式直观展示。词云的用法可以参照之前的例子:《核安全法》词云统计,以下为实现代码:
# 获取所有txt文件,读入内容
def get_word():
files = []
for file in os.listdir('.'):
if file.endswith('.txt'):
files.append(file)
total_content = ''
for file_num in range(len(files)):
with open(files[file_num],'rb') as f:
txt = f.read()
decode_txt = txt.decode('utf-8')
total_content += decode_txt
words_ls = jieba.lcut(total_content)
return words_ls
# 生成词云
def ciyun():
mk = imread('qianlong.jpg')
words_ls = get_word()
words = ' '.join(words_ls)
w = wordcloud.WordCloud(mask=mk,font_path='msyh.ttc',background_color='white')
w.generate(words)
w.to_file('延禧词云.png')
print('词云生成成功!')
以下为词云效果,主角永远都是讨论的焦点:
词频统计
评论区大家讨论最多的是哪些角色呢?我们通过词频统计来看下。词频统计采取字典的get方法,详细可见前面的介绍:《水浒传》词频统计,组合数据类型(2)。我们统计出现最多的前十名,以下为实现代码:
def ciping():
words = get_word()
# print(words)
counter = {}
del_words = [
'','一个','没有','自己','就是','觉得','这个','真的','...','什么','不是','还是',
'喜欢','延禧','但是','攻略','知道','看到','剧情','这么','可以','时候','最后','怎么','感觉',
'演技','那么','所以','其实','为什么','这样','为了','还有'
]
for word in words:
if len(word) == 1:
continue
elif word == '女主':
return_word = '璎珞'
elif word == '乾隆' or word == '皇帝':
return_word = '皇上'
else:
return_word = word
counter[return_word] = counter.get(return_word,0) + 1
for word in del_words:
del counter[word]
ls = list(counter.items())
ls.sort(key=lambda x:x[1],reverse=True)
for i in range(10):
print(ls[i])
运行后的结果为:
可以看到主角毫无疑问的第一位,接下来就是大猪蹄子乾隆皇帝,温文尔雅的皇后位居第三,袁春望出现在前十有点意外。不知道《延禧》,你给几分?
网友评论