Python极简爬虫实战:12行代码获取豆瓣短评数据

📅 2026/7/18 2:38:52 👁️ 阅读次数 📝 编程学习
Python极简爬虫实战:12行代码获取豆瓣短评数据

1. 项目背景与核心思路

去年帮朋友做影视数据分析时,需要快速获取《黑豹》的豆瓣短评数据。传统爬虫教程往往从零开始搭建完整框架,但对于这种轻量级需求,其实用Python标准库+requests就能12行代码搞定。这种极简爬虫特别适合临时数据采集需求,无需复杂环境配置,直接上手就能跑通。

核心原理是利用requests模拟浏览器请求,通过豆瓣短评接口获取JSON数据。这里有个关键技巧:豆瓣对未登录用户只开放前20页短评(每页20条),而登录后可爬取更多数据。不过要注意频率控制,实测连续请求超过10次/分钟会触发429错误。

2. 环境准备与工具选型

2.1 基础环境配置

推荐使用Python 3.6+版本,主要依赖两个库:

pip install requests pip install pandas # 非必须,用于数据整理

选择requests库而非Scrapy等框架的原因:

  • 轻量级:无需创建完整爬虫项目
  • 学习成本低:API设计直观,适合新手
  • 调试方便:直接打印响应内容

2.2 接口分析技巧

通过Chrome开发者工具抓包发现:

  1. 短评接口格式:https://movie.douban.com/subject/[电影ID]/comments?start=[偏移量]&limit=20
  2. 《黑豹》电影ID:5360029
  3. 关键参数:
    • start:分页偏移量(0,20,40...)
    • limit:固定值20

注意:务必添加User-Agent头部,否则会返回403错误。实测可用的UA:'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'

3. 核心代码实现与解析

3.1 基础爬取代码

import requests headers = {'User-Agent': 'Mozilla/5.0'} comments = [] for i in range(0, 200, 20): # 爬10页数据 url = f'https://movie.douban.com/subject/5360029/comments?start={i}' resp = requests.get(url, headers=headers) comments.extend([item['content'] for item in resp.json()['comments']]) print(f'已获取第{i//20+1}页数据')

代码关键点解析:

  1. range(0, 200, 20):控制爬取页数(200=10页×20条)
  2. resp.json():自动解析JSON响应
  3. 列表推导式:快速提取评论内容

3.2 异常处理增强版

实际运行时会遇到各种异常,建议增加以下处理:

import time from random import uniform for i in range(0, 200, 20): try: resp = requests.get(url, headers=headers, timeout=10) resp.raise_for_status() # 检查HTTP错误 data = resp.json() if 'comments' not in data: print('可能触发反爬,尝试降低频率') break comments.extend([item['content'] for item in data['comments']]) time.sleep(uniform(0.5, 1.5)) # 随机延迟 except Exception as e: print(f'第{i//20+1}页出错:{str(e)}') break

4. 反爬机制与应对策略

4.1 豆瓣的反爬措施

  • 频率限制:单IP请求过快会返回429状态码
  • User-Agent验证:缺失或不常见的UA会被拦截
  • Cookie验证:部分接口需要携带登录态
  • 行为分析:连续规律请求可能触发验证码

4.2 合规爬取建议

  1. 遵守robots.txt规则:
    • 豆瓣允许爬取电影页面,但禁止商业用途
    • 建议间隔请求至少1秒以上
  2. 使用代理IP池(需自行搭建):
    proxies = {'http': 'http://your_proxy:port'} requests.get(url, proxies=proxies)
  3. 获取公开API权限:
    • 豆瓣开放平台提供正式API接口
    • 需要申请API Key并遵守调用限制

5. 数据存储与分析示例

5.1 存储到CSV文件

import pandas as pd df = pd.DataFrame({'comment': comments}) df.to_csv('black_panther_comments.csv', index=False, encoding='utf-8-sig')

5.2 简单词频分析

from collections import Counter import jieba # 中文分词库 text = ' '.join(comments) words = [w for w in jieba.cut(text) if len(w) > 1] # 过滤单字 word_counts = Counter(words).most_common(20) print('高频词Top20:', word_counts)

6. 常见问题排查指南

问题现象可能原因解决方案
返回403错误缺少User-Agent或Cookie添加合法UA头
返回429错误请求频率过高增加延迟或使用代理
JSON解析失败接口返回HTML验证页检查响应内容格式
数据缺失页面结构变更更新CSS选择器/XPath
连接超时网络问题或IP被封更换网络环境

7. 进阶优化方向

  1. 登录态保持:使用session对象保存cookies

    session = requests.Session() session.post(login_url, data=credentials) session.get(api_url) # 自动携带cookies
  2. 异步爬取提升效率:

    import aiohttp async with aiohttp.ClientSession() as session: async with session.get(url) as resp: data = await resp.json()
  3. 使用Selenium应对动态渲染:

    from selenium import webdriver driver = webdriver.Chrome() driver.get(url) comments = driver.find_elements_by_css_selector('.comment-item')

我在实际爬取时发现,工作日下午的请求成功率明显高于晚间高峰时段。建议在代码中添加自动重试机制,当连续3次请求失败后,暂停10分钟再继续。另外保存中间结果到文件也很重要,避免程序中断导致数据丢失。