Python爬虫实战,《哪吒2》豆瓣短评数据爬取

春节档向来是影视圈的兵家必争之地,而今年,一部《哪吒 2》强势闯入大众视野,瞬间点燃了观众们的热情。社交媒体上,关于哪吒新冒险的讨论铺天盖地,大家对这部续作的评价褒贬不一。你是否好奇,在豆瓣这个影视评分的重要阵地,广大影迷们究竟给出了怎样的短评?是对特效的惊艳赞叹,还是对剧情的深度剖析?

今天,我们就将借助 Python 爬虫这一强大工具,深入豆瓣,揭开《哪吒 2》短评数据的神秘面纱,看看这些数据背后,藏着怎样的观众心声。

《哪吒 2》的评论数据的地址如下,主要包含"用户昵称"、 "评分"、 "评论时间"、 "用户地址"、 "评论内容"这些字段,我们要爬取的也是这些内容。

电影网址:https://movie.douban.com/subject/34780991/comments?status=P

熟悉爬虫的同学应该知道,一个完整的爬虫应该包含以下几个过程:

数据抓取:

使用随机延时(3-5秒)规避反爬机制
模拟浏览器请求头(含User-Agent/Referer/Host)
支持分页抓取(每页20条,共抓100条)
数据解析:

精确提取五个关键字段:

用户昵称(.comment-info a)
星级评分(allstar开头的class值转换)
评论时间(.comment-time的title属性)
用户地址(.comment-location)
评论内容(.comment-content)
数据存储:

通过pandas构建结构化数据表
按指定字段顺序导出Excel(无索引列)
1.requests发送请求
电影网址:https://movie.douban.com/subject/34780991/comments?status=P

常见状态码示例:

200:爬虫成功获取页面内容。
403:爬虫被反爬机制拦截,需要添加请求头或使用代理。
404:目标页面不存在,检查 URL 是否正确。
500:服务器内部错误,可能是目标网站的问题。


In [1]:
import requests

# 目标URL
url = "https://movie.douban.com/subject/34780991/comments?status=P"

# 设置请求头,模拟浏览器访问
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}

# 发送GET请求
response = requests.get(url, headers=headers)

# 返回状态码
print("状态码:", response.status_code)
状态码: 200
2.BeautifulSoup数据解析
在数据解析方面,需要注意在检查元素里面的位置,依次右键网页➔检查➔Elements➔鼠标悬停文本内容➔找到元素的位置➔使用BeautifulSoup解析。

3.数据保存
构建一个空表用来保存数据。

In [2]:
import pandas as pd

# 创建空DataFrame(带表头)
columns = ["用户昵称", "评分", "评论时间", "用户地址", "评论内容"]
df = pd.DataFrame(columns=columns)

# 保存为Excel文件
df.to_excel("comments.xlsx", index=False)
同时,通过点击菜单,发现了该网页的点击规律,该网页的

第一页:https://movie.douban.com/subject/34780991/comments?limit=20&status=P&sort=new_score
第二页:https://movie.douban.com/subject/34780991/comments?start=20&limit=20&status=P&sort=new_score
第三页:https://movie.douban.com/subject/34780991/comments?start=40&limit=20&status=P&sort=new_score

网页的翻页规律是通过start=0,start=20,start=40,每翻一页,start递增20的翻页规律,这样方便我们构造翻页规律。

综上,我们写出完整版代码如下,注意,这里为了避免被反爬,设置了请求头以及延时数据爬取,这样避免被反爬。

In [3]:
import requests
import random
import time
import pandas as pd
from bs4 import BeautifulSoup

# 使用 User-Agent
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"

def get_headers():
    """固定请求头"""
    return {
        'User-Agent': USER_AGENT,
        'Referer': 'https://movie.douban.com/',
        'Host': 'movie.douban.com'
    }

def parse_comment(item):
    """解析单个评论条目"""
    comment = {}
    
    # 用户昵称
    username_tag = item.select_one('.comment-info a')
    comment['用户昵称'] = username_tag.text.strip() if username_tag else ''
    
    # 评分
    rating_tag = item.select_one('span[class^="allstar"]')
    if rating_tag:
        rating_class = rating_tag.get('class', [''])[0]
        comment['评分'] = int(rating_class.replace('allstar', '')) // 10
    else:
        comment['评分'] = '无评分'
    
    # 评论时间
    time_tag = item.select_one('.comment-time')
    comment['评论时间'] = time_tag.get('title').strip() if time_tag else ''
    
    # 用户地址
    location_tag = item.select_one('.comment-location')
    comment['用户地址'] = location_tag.text.strip() if location_tag else ''
    
    # 评论内容
    content_tag = item.select_one('.comment-content')
    comment['评论内容'] = content_tag.text.strip() if content_tag else ''
    
    return comment

def get_comments(url):
    """获取单页评论数据"""
    try:
        response = requests.get(url, headers=get_headers(), timeout=10)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'lxml')
        items = soup.select('.comment-item')
        return [parse_comment(item) for item in items]
    except Exception as e:
        print(f'请求失败:{url},错误:{e}')
        return []

def main():
    base_url = 'https://movie.douban.com/subject/34780991/comments'
    all_comments = []
    
    for page in range(5):
        # 构造分页URL
        start = page * 20
        url = f'{base_url}?start={start}&limit=20&status=P&sort=new_score'
        
        # 获取数据
        print(f'正在爬取第 {page + 1} 页...')
        comments = get_comments(url)
        all_comments.extend(comments)
        
        # 随机延时
        sleep_time = random.uniform(3, 5)
        print(f'等待 {sleep_time:.2f} 秒...')
        time.sleep(sleep_time)
    
    # 保存数据,按指定顺序排列字段
    columns_order = ['用户昵称', '评分', '评论时间', '用户地址', '评论内容']
    df = pd.DataFrame(all_comments, columns=columns_order)
    df.to_excel('豆瓣电影评论数据.xlsx', index=False)
    print('数据已保存到 豆瓣电影评论数据.xlsx')

if __name__ == '__main__':
    main()
正在爬取第 1 页...
等待 3.80 秒...
正在爬取第 2 页...
等待 4.39 秒...
正在爬取第 3 页...
等待 3.87 秒...
正在爬取第 4 页...
等待 4.59 秒...
正在爬取第 5 页...
等待 4.11 秒...
数据已保存到 豆瓣电影评论数据.xlsx
爬取后的评论数据在文件树的project文件夹下,将影评数据导入以后,可以看到每一个用户的评价,基于该文本评论数据,可以进一步的做文本分析,研究观众对于该电影的口碑情况。

In [4]:
import pandas as pd

df = pd.read_excel('/home/mw/project/豆瓣电影评论数据.xlsx')
df.head()
用户昵称    评分    评论时间    用户地址    评论内容
0    海底    5    2025-01-31 10:30:26    浙江    申公豹:小镇做题家的一生
1    Fang    3    2025-01-29 13:46:29    河北    烦透了这种高层隐身、中层搞事、底层遭殃的设定,无数次看得我血压飙升,哪吒虽然设定是魔,行事倒...
2    朝暮雪    3    2025-01-29 16:12:06    四川    很多桥段很低俗,第一部就有这样的问题,但就是不改,因为导演觉得拍得再低俗都有大把的人去看,不...
3    丁小雨    4    2025-01-31 12:41:23    广西    感觉“我命由我不由天”的是申公豹,申公豹真的好努力,努力的小镇做题家,努力攀附强者才能让自己...
4    Ber_雪碧    5    2025-01-29 11:29:10    北京    好看到超出预期,打破了对哪吒闹海神话传说的既定想象,为故事塑造了符合时代的全新内核。第一部讲...

以上,通过 Python 爬虫,我们成功获取了《哪吒 2》的豆瓣短评数据,这不仅是一次有趣的爬虫实战,更是一次数据驱动的影视分析探索。希望大家能从这次实践中,感受到 Python 爬虫在获取信息、挖掘价值方面的强大力量。不妨自己动手,尝试对这些数据进行更深入的分析,相信你会发现更多有趣的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴躁的秋秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值