Python实战:手把手教你高效抓取豆瓣电视剧评论数据 (附代码示例)57


爬虫抓取豆瓣电视剧评论



大家好,我是你们的中文知识博主。今天我们要聊一个非常热门且实用的话题:如何使用Python爬虫技术,从豆瓣电影(特别是电视剧)页面抓取用户评论数据。无论是为了进行市场分析、观众情绪洞察,还是仅仅满足你的好奇心,掌握这项技能都将为你的数据世界打开一扇新的大门。


豆瓣作为国内知名的影视内容社区,积累了海量的用户评论。这些评论不仅包含了观众对作品的直接反馈,更蕴藏着丰富的社会文化信息和潜在的商业价值。通过数据抓取,我们可以对这些评论进行批量分析,发现热门话题、情感趋势,甚至是预测作品的口碑走向。本篇文章将带你从零开始,一步步实现豆瓣电视剧评论的抓取,并分享一些实用的技巧和注意事项。

爬虫前奏:法律与道德的边界



在正式动手写代码之前,我们必须先强调“爬虫伦理”和“法律合规性”。

尊重Robots协议: 几乎所有网站都会有一个``文件(如`/`),它规定了爬虫可以访问哪些页面,不可以访问哪些页面。在抓取前务必查看并遵守。
控制请求频率: 不要过于频繁地向目标网站发送请求,这可能会给服务器带来压力,导致你的IP被封禁。建议设置合理的延迟(如`()`)。
合理使用数据: 抓取到的数据仅供学习、研究和个人分析使用。严禁用于商业用途、侵犯用户隐私或任何非法目的。
公开数据源: 如果你公开分享基于抓取数据得出的分析结果,请注明数据来源是豆瓣,并尊重其知识产权。

记住,做一个负责任的爬虫开发者,是进行数据抓取的前提。

工具箱:Python与核心库



本次教程我们将主要使用Python语言,以及以下几个核心库:

`requests`: 用于发送HTTP请求,获取网页的HTML内容。
`BeautifulSoup`: 一个强大的HTML/XML解析库,能够从网页中提取我们所需的数据。
`pandas`: 用于数据处理和存储,方便我们将抓取到的数据整理成表格形式(如CSV文件)。
`time`: 用于设置请求间隔,避免被反爬。

如果你还没有安装这些库,可以通过pip进行安装:
pip install requests beautifulsoup4 pandas

实战演练:抓取豆瓣电视剧评论核心步骤



我们将以豆瓣某部电视剧的评论页为例(例如:《漫长的季节》),来讲解具体的操作步骤。
示例电视剧URL:`/subject/35633045/`
进入评论页:点击页面上的“全部短评”或“全部影评”链接。通常短评页面的URL会有`comments?status=P`的参数。
例如:`/subject/35633045/comments?start=0&limit=20&status=P&sort=new_score`

Step 1: 目标分析与URL定位



首先,我们需要找到评论页面的URL规律。观察上述URL,可以发现`start=0`代表从第0条评论开始,`limit=20`代表每页显示20条。翻页时,`start`参数会以20的步长递增(0, 20, 40, ...)。这就是我们实现多页抓取的关键。
此外,我们还需要通过浏览器开发者工具(按F12)查看网页结构,找到评论者名称、评论内容、评分、时间等元素对应的HTML标签和CSS类。
例如,一个评论块通常可能长这样:

<div class="comment-item">
<h3>
<span class="comment-info">
<a href="..." class="comment-user">用户名</a>
<span class="rating" title="力荐"></span> <!-- 评分 -->
<span class="comment-time" title="2023-04-20 18:00:00">2023-04-20</span>
</span>
</h3>
<p class="comment-content">
<span class="short">评论内容...</span>
</p>
<div class="comment-vote">
<span class="vote-count">20</span>
</div>
</div>

通过观察,我们可以初步确定:

用户名:可能在`a`标签中,`class`为`comment-user`。
评分:可能在`span`标签中,`class`为`rating`,`title`属性记录了具体评分(如“力荐”)。
评论时间:可能在`span`标签中,`class`为`comment-time`,`title`属性记录了完整时间。
评论内容:可能在`p`标签中,`class`为`comment-content`,内部的`span`标签,`class`为`short`。

Step 2: 发送HTTP请求



使用`requests`库向目标URL发送请求,获取页面内容。为了模拟浏览器访问,我们需要在请求头中添加`User-Agent`。

import requests
import time
from bs4 import BeautifulSoup
import pandas as pd
# 电视剧ID,例如《漫长的季节》的ID是 35633045
tv_series_id = '35633045'
base_url = f'/subject/{tv_series_id}/comments'
# 模拟浏览器访问,设置User-Agent
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# 还可以添加其他headers,例如Cookie,如果需要登录才能访问
}
def get_page_content(url, headers):
try:
response = (url, headers=headers, timeout=10)
response.raise_for_status() # 检查HTTP响应状态,如果不是200则抛出异常
= 'utf-8' # 设置编码,防止乱码
return
except as e:
print(f"请求失败: {url} - {e}")
return None
# 测试获取第一页内容
first_page_url = f"{base_url}?start=0&limit=20&status=P&sort=new_score"
html_content = get_page_content(first_page_url, headers)
if html_content:
print("成功获取第一页内容,长度:", len(html_content))
else:
print("获取内容失败。")

Step 3: 解析HTML内容并提取数据



获取到HTML内容后,使用`BeautifulSoup`进行解析,并根据前面分析的HTML结构提取所需信息。

def parse_comments(html):
soup = BeautifulSoup(html, 'lxml')
comments_list = []

# 查找所有评论项
comment_items = soup.find_all('div', class_='comment-item')

for item in comment_items:
user_name = ('a', class_='comment-user')
user_name = () if user_name else 'N/A'

rating_span = ('span', class_='rating')
rating = rating_span['title'].strip() if rating_span and 'title' in else 'N/A'

comment_time = ('span', class_='comment-time')
comment_time = comment_time['title'].strip() if comment_time and 'title' in else 'N/A'

comment_content_span = ('span', class_='short')
comment_content = () if comment_content_span else 'N/A'
vote_count_span = ('span', class_='vote-count')
vote_count = () if vote_count_span else '0'

({
'用户名': user_name,
'评分': rating,
'评论时间': comment_time,
'评论内容': comment_content,
'点赞数': int(vote_count)
})
return comments_list
# 测试解析第一页评论
if html_content:
first_page_comments = parse_comments(html_content)
print(f"第一页解析到 {len(first_page_comments)} 条评论。")
if first_page_comments:
print(first_page_comments[0]) # 打印第一条评论查看效果

Step 4: 翻页与批量抓取



通过修改`start`参数循环抓取多页数据。同时,为了避免触发反爬机制,我们需要在每次请求之间添加`()`。

all_comments_data = []
max_pages = 50 # 设定最大抓取页数,每页20条评论,50页就是1000条。根据需求调整
page_size = 20 # 每页评论数量
print(f"开始抓取豆瓣电视剧评论 (ID: {tv_series_id})...")
for i in range(max_pages):
start_index = i * page_size
page_url = f"{base_url}?start={start_index}&limit={page_size}&status=P&sort=new_score"
print(f"正在抓取第 {i+1} 页,URL: {page_url}")

html = get_page_content(page_url, headers)
if html:
comments = parse_comments(html)
if not comments: # 如果当前页没有评论,说明已经抓取完毕或遇到问题
print("当前页没有获取到评论,可能已达到最大页数或遇到反爬机制。")
break
(comments)
print(f"已抓取到 {len(all_comments_data)} 条评论。")
else:
print(f"获取第 {i+1} 页失败,跳过。")
(2 + i % 3) # 设置随机一点的延迟,模拟人类行为,避免被封

print(f"评论抓取完毕,共抓取到 {len(all_comments_data)} 条评论。")

Step 5: 数据存储与整合



将抓取到的数据存储为CSV文件,方便后续的数据分析。

# 将数据转换为Pandas DataFrame
df = (all_comments_data)
# 保存为CSV文件
output_filename = f'douban_tv_series_{tv_series_id}'
df.to_csv(output_filename, index=False, encoding='utf-8-sig') # 使用utf-8-sig避免中文乱码
print(f"数据已成功保存到 {output_filename}")
print("前5行数据预览:")
print(())

挑战与进阶:防爬机制与动态加载



上述代码对于豆瓣短评页这种相对静态的页面是有效的。但在实际爬取中,你可能会遇到以下挑战:

IP封锁: 频繁请求可能导致你的IP被暂时或永久封禁。解决方案包括使用代理IP池、更换IP、延长请求间隔等。
User-Agent检测: 网站会检查`User-Agent`,如果不是常见的浏览器标识,可能会拒绝访问。可以维护一个`User-Agent`列表进行随机切换。
验证码: 某些网站会在检测到异常行为后弹出验证码,阻止爬虫。这通常需要手动输入或接入打码平台。
JavaScript动态加载: 如果评论内容是通过JavaScript异步加载的(AJAX请求),`requests`库将无法直接获取。这时你需要使用`Selenium`等自动化测试工具,模拟浏览器行为来加载JS内容。不过,豆瓣的短评页面通常是直接在HTML中的,所以本教程的方法依然适用。
Cookie/Session管理: 某些网站需要登录才能访问,或者通过Cookie来维护用户会话。你可能需要获取并维护Cookie信息。

对于豆瓣评论,大部分情况下,上述的基础爬虫方法已经足够应对。

数据价值:从评论到洞察



一旦你成功抓取了评论数据,接下来就是发挥其价值的时候了:

情感分析: 对评论内容进行情感倾向分析(正面、负面、中性),了解观众的整体情绪。
关键词提取与词云: 提取高频词汇,生成词云图,直观展现评论的焦点。
时间趋势分析: 结合评论时间,分析作品口碑随时间的变化,看是否存在“高开低走”或“低开高走”的情况。
用户画像: 分析不同评分用户的评论特征,尝试构建用户画像。
内容主题分析: 通过主题模型(如LDA)发现评论中隐藏的主题和话题。

这些分析结果将帮助你更深入地理解作品、观众和市场。

结语



通过本篇文章,你已经掌握了使用Python进行豆瓣电视剧评论抓取的基本流程和核心代码。从网页分析到数据提取,再到数据存储,每一步都详细讲解,并提供了可直接运行的代码示例。
请记住,技术是一把双刃剑,合理合法地使用爬虫技术,不仅能为我们提供丰富的数据洞察,也能避免不必要的法律风险。希望这篇教程能为你打开数据世界的大门,祝你在数据探索的旅程中取得丰硕的成果!如果你有任何疑问或想分享你的爬虫成果,欢迎在评论区留言交流!

2025-10-01


上一篇:《请融化我》评分深度解析:池昌旭荧屏回归为何“高开低走”?

下一篇:《最美的乡村》深度解析:一部关乎中国乡村振兴的时代画卷