1. 项目背景与核心思路去年帮朋友做影视数据分析时需要快速获取《黑豹》的豆瓣短评数据。传统爬虫教程往往从零开始搭建完整框架但对于这种轻量级需求其实用Python的requests库配合几行正则就能暴力破解。这个方法虽然不够优雅但在小规模数据抓取场景下效率极高。核心原理很简单豆瓣短评页面的HTML结构相对固定我们只需要用requests模拟浏览器请求从返回的HTML中提取评论文本处理分页逻辑循环抓取注意实际操作前请务必检查豆瓣的robots.txt协议控制请求频率在合理范围。我测试时设置了2秒间隔既不会触发反爬机制也能在1分钟内完成基础数据采集。2. 环境准备与工具选型2.1 基础环境配置推荐使用Python 3.8版本主要依赖两个库pip install requests regex选择requests而非urllib的原因更简洁的API设计对比urllib的urlencode等繁琐操作自动处理连接池和Keep-Alive内置SSL验证等安全特性2.2 反爬应对策略豆瓣对高频请求有严格限制实测中发现两个关键点需要添加合理的请求头headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept-Language: zh-CN,zh;q0.9 }必须控制请求间隔import time time.sleep(random.uniform(1, 3)) # 随机间隔更安全3. 核心代码实现解析3.1 页面请求模块import requests def get_page(url): try: r requests.get(url, headersheaders) r.raise_for_status() # 自动处理HTTP错误 r.encoding r.apparent_encoding return r.text except requests.exceptions.RequestException as e: print(f请求失败: {e}) return None这段代码的关键点raise_for_status()会自动检查4xx/5xx状态码使用apparent_encoding能更准确识别页面编码异常捕获包含连接超时、SSL错误等常见问题3.2 数据提取模块豆瓣短评的HTML结构类似div classcomment-item span classshort这是评论内容/span /div使用正则表达式提取import re pattern re.compile(rspan classshort(.*?)/span) comments pattern.findall(html)相比BeautifulSoup正则的优势无需解析整个DOM树内存占用更小速度更快实测快3-5倍3.3 分页处理逻辑观察豆瓣分页规则发现URL规律https://movie.douban.com/subject/123456/comments?start20limit20通过修改start参数实现翻页base_url https://movie.douban.com/subject/123456/comments for i in range(0, 200, 20): # 抓取前10页 url f{base_url}?start{i}limit20 html get_page(url) # 处理提取逻辑...4. 完整代码实现import requests, re, time, random headers {User-Agent: Mozilla/5.0} pattern re.compile(rspan classshort(.*?)/span) def crawl(start0): url fhttps://movie.douban.com/subject/6390825/comments?start{start} html requests.get(url, headersheaders).text comments pattern.findall(html) for cmt in comments: print(cmt.strip()) time.sleep(random.uniform(1, 3)) for i in range(0, 100, 20): crawl(i)代码优化点使用随机睡眠时间避免固定间隔被识别限制总请求量在合理范围这里设置5页输出时用strip()去除空白字符5. 常见问题与解决方案5.1 返回429错误典型表现requests.exceptions.HTTPError: 429 Client Error解决方法增加延迟时间到3-5秒添加更多请求头伪装headers.update({ Accept: text/html,application/xhtmlxml, Connection: keep-alive })5.2 中文乱码问题如果出现乱码需要手动指定编码r.encoding utf-8 # 强制使用UTF-85.3 数据重复或缺失可能原因分页参数计算错误正则表达式匹配不准确 排查方法with open(debug.html, w, encodingutf-8) as f: f.write(html) # 保存原始HTML人工检查6. 进阶优化方向6.1 使用代理IP池当需要大规模采集时建议使用proxies { http: http://10.10.1.10:3128, https: http://10.10.1.10:1080 } requests.get(url, proxiesproxies)6.2 数据持久化存储推荐保存为CSV格式import csv with open(comments.csv, a, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([comment, rating, time]) # 需要先提取这些字段6.3 异步请求优化对于高性能需求可用aiohttpimport aiohttp async with aiohttp.ClientSession() as session: async with session.get(url) as resp: return await resp.text()我在实际项目中总结的经验是对于临时性数据需求这种暴力方法效率最高但如果是长期项目建议还是用Scrapy等框架构建完整爬虫并严格遵守网站的爬取政策。