豆瓣电影评论爬取并词云可视化(附代码)

1.库准备
import requests
import time
import random
import pandas as pd
import jieba
from lxml import etree
from stylecloud import gen_stylecloud
2.爬虫块,从豆瓣电影爬取评论100条短评(例如);
def spider():
# 以龙岭迷窟为例(如果需要别的电影,只需替换电影对应代码)
url_comment = 'https://movie.douban.com/subject/35215390/comments?start=%d&limit=20&sort=new_score&status=P'
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36',
"Referer": "https://movie.douban.com/subject/35215390/comments"
}

# 初始化存储列表
users = []
stars = []
times = []
content = []

# 爬取5页(100条,避免爬取过多被限制)
for i in range(0, 100, 20):
    try:
        # 发送请求
        session = requests.session()
        response = session.get(url_comment % i, headers=headers, timeout=10)
        print(f'第{i//20 + 1}页,状态码:{response.status_code}')
        
        # 解析HTML
        selector = etree.HTML(response.text)
        comments = selector.xpath('//div[@class="comment"]')
        
        for comment in comments:
            # 用户名
            user = comment.xpath('.//h3/span[2]/a/text()')
            # 评分(可能没有评分)
            star = comment.xpath('.//h3/span[2]/span[2]/@class')
            # 时间
            date_time = comment.xpath('.//h3/span[2]/span[3]/@title')
            # 评论内容
            comment_text = comment.xpath('.//p/span/text()')
            
            # 避免索引错误,只保留有完整信息的数据
            if user and comment_text:
                users.append(user[0])
                stars.append(star[0][7:8] if star else '无评分')
                times.append(date_time[0][:10] if date_time else '无时间')
                content.append(comment_text[0].strip())
        
        # 随机暂停,避免被封
        time.sleep(random.uniform(1, 2))
        
    except Exception as e:
        print(f'第{i//20 + 1}页爬取失败:{e}')
        continue

# 保存数据到CSV
comment_dic = {
    'user': users,
    'star': stars,
    'time': times,
    'comments': content
}
comment_df = pd.DataFrame(comment_dic)
comment_df.to_csv('douban_comments.csv', encoding='utf-8-sig')  # 用utf-8-sig避免中文乱码
print(f'爬取完成,共{len(comment_df)}条数据,已保存为 douban_comments.csv')

执行爬取

spider()
3.数据处理并生成词云

读取数据(确保文件存在)

try:
df = pd.read_csv('douban_comments.csv', index_col=0)
except FileNotFoundError:
print("数据文件不存在,请检查爬取是否成功")
exit()

提取评论并清洗

cts_list = df['comments'].dropna().values.tolist() # 去除空值
cts_str = "".join([str(i).replace('\n', '').replace(' ', '') for i in cts_list])

内置基础停用词(有条件可以下载网上的stop_words文件,这里只是做了简单的分词处理,比较粗糙)

stop_words = [
'的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也',
'很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这', '部', '电影',
'片子', '觉得', '比较', '还', '但', '而', '让', '被', '挺', '啊', '呢', '吧', '啦', '之', '与'
]

结巴分词并过滤停用词

jieba.setLogLevel(jieba.logging.INFO) # 关闭jieba日志
word_list = jieba.cut(cts_str)
words = [word for word in word_list if word not in stop_words and len(word) > 1] # 过滤单字
cts_clean = ' '.join(words) # 用空格分隔词语(stylecloud需要空格分隔)

生成词云

try:
gen_stylecloud(
text=cts_clean,
max_words=200,
collocations=False,
font_path="simhei.ttf", # 系统默认黑体(大部分Windows有)
icon_name="fas fa-film", # 电影相关图标,这里也可以改,词云内置有自己的形状,比如爱心对应代码fas fa-heart,替换即可
size=800,
output_name="douban_comment_wordcloud.png"
)
print("词云生成成功:douban_comment_wordcloud.png")
# 显示词云(仅在Jupyter中有效)
Image(filename="douban_comment_wordcloud.png")
except Exception as e:
print(f'词云生成失败:{e}')
至此得到效果图:
image

posted @ 2025-11-07 09:51  Wannahug  阅读(5)  评论(0)    收藏  举报