当前位置: 首页 > news >正文

Python爬虫实战:突破懒加载,自动化批量下载抖音用户全量视频

1. 懒加载机制与爬虫挑战

抖音网页版采用的懒加载技术,本质上是一种优化用户体验的设计。当用户浏览到页面底部时,系统才会动态加载新的内容。这种机制对普通用户很友好,但对爬虫开发者来说却是个头疼的问题。

我最初尝试用requests直接请求API时,发现只能获取到第一屏的18个视频。这就像去餐厅吃饭,服务员每次只给你上一道菜,吃完才给下一道,想一次性看到所有菜品根本不可能。抖音的API设计也是如此,需要不断传递max_cursor参数才能获取后续内容。

更麻烦的是,抖音的接口参数非常复杂。除了常规的User-Agent和Cookie,还有像msToken、a_bogus这样的动态加密参数。这些参数不仅会定期更换,还和用户行为、设备信息等挂钩。有次我连续请求20次后,突然收到403错误,原来是被系统识别出了爬虫行为。

2. 基础方案:API直接请求

先来看最基础的实现方式。通过浏览器开发者工具,我们可以找到抖音的视频列表API。这个接口通常长这样:

url = 'https://www.douyin.com/aweme/v1/web/aweme/post/?device_platform=webapp&aid=6383&sec_user_id=用户ID&max_cursor=0&count=18'

关键参数说明:

  • sec_user_id: 用户唯一标识,从个人主页URL获取
  • max_cursor: 分页游标,初始为0
  • count: 每次请求返回的视频数量(实测最大不超过20)

请求头需要包含:

headers = { 'User-Agent': 'Mozilla/5.0...', 'Referer': 'https://www.douyin.com/user/...' }

但这个方法有三个致命缺陷:

  1. 无法获取全量视频,每次最多20条
  2. 需要处理动态加密参数(如a_bogus)
  3. 高频请求极易触发风控

我曾用这个方案爬取某网红的前100个视频,结果到第60个时就IP被封了。后来发现抖音的防爬策略会检测:

  • 请求频率
  • 请求头完整性
  • 鼠标移动轨迹(对API请求无效)

3. 进阶方案:浏览器自动化

为了解决上述问题,我转向了浏览器自动化方案。这里推荐使用DrissionPage(国人开发的库),它比Selenium更轻量,而且内置了请求监听功能。

核心思路是模拟真实用户操作:

  1. 打开浏览器登录抖音(解决认证问题)
  2. 进入目标用户主页
  3. 自动/手动滚动页面触发懒加载
  4. 拦截API返回的视频数据

具体实现分为几个关键步骤:

3.1 环境配置

首先安装依赖:

pip install DrissionPage tqdm requests

初始化浏览器:

from DrissionPage import ChromiumPage page = ChromiumPage() page.get('https://www.douyin.com/')

这里有个坑要注意:抖音会检测浏览器指纹。我测试时发现,用默认配置会被识别为自动化工具。解决方法是指定用户数据目录:

page = ChromiumPage(user_data_dir='./user_data')

3.2 登录与认证

抖音必须登录才能查看完整视频列表。我们可以手动登录后保存cookies:

input("请手动登录后按回车继续...") page.cookies.save() # 保存cookies供下次使用

更自动化的方案是通过扫码登录,但这需要处理抖音的加密协议,复杂度较高。我建议首次运行时手动登录,后续复用cookies。

3.3 滚动加载控制

核心的滚动监听代码如下:

page.listen.start('aweme/post') # 监听视频接口 page.get(user_url) while len(videos) < target_count: page.scroll.down(500) # 向下滚动500像素 time.sleep(random.uniform(1, 3)) # 随机等待 resp = page.listen.wait() if resp and resp.json().get('aweme_list'): videos.extend(resp.json()['aweme_list'])

这里有几个优化点:

  1. 滚动幅度不要太大,模仿人类操作
  2. 随机等待时间避免规律性请求
  3. 设置合理的超时退出条件

我实测下来,这种方式能稳定获取200+视频而不被封禁。关键是要模拟真实用户行为,包括:

  • 偶尔的暂停浏览
  • 不规律的滚动速度
  • 随机的鼠标移动

4. 视频下载与存储

获取到视频列表后,下载环节也有不少坑。抖音的视频地址通常是这样的结构:

video_url = video['video']['play_addr']['url_list'][0]

但直接下载可能会遇到:

  1. 链接过期(302重定向)
  2. 限速(下载到一半断开)
  3. 文件名非法字符

我的解决方案是:

def download_video(url, save_path): headers = {'Referer': 'https://www.douyin.com/'} with requests.get(url, headers=headers, stream=True) as r: with open(save_path, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk)

加上重试机制和断点续传:

max_retries = 3 for attempt in range(max_retries): try: download_video(url, path) break except Exception as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # 指数退避

对于文件名问题,需要清洗特殊字符:

import re def clean_filename(name): return re.sub(r'[\\/*?:"<>|]', "_", name)

5. 反爬策略应对

抖音的反爬手段在不断升级,最近遇到的挑战包括:

  1. 行为验证(滑块验证码)
  2. 设备指纹识别
  3. 请求参数加密

我的应对经验是:

  • 使用真实浏览器环境(不要用无头模式)
  • 随机化操作间隔时间
  • 定期更换IP(建议使用家庭宽带动态IP)
  • 避免在高峰期密集爬取

有个实用的技巧:通过修改浏览器窗口大小来规避检测:

page.set.window.size(1200, 800) # 设置为常见分辨率

如果遇到验证码,可以尝试这些方法:

  1. 自动识别简单验证码(成功率约70%)
  2. 人工打码平台(成本较高)
  3. 暂停任务等待验证过期(约30分钟)

6. 完整代码实现

结合上述技术点,这是优化后的完整代码框架:

from DrissionPage import ChromiumPage import requests, time, random class DouyinCrawler: def __init__(self): self.page = ChromiumPage(user_data_dir='./user_data') def login(self): self.page.get('https://www.douyin.com/') input("请手动登录后按回车继续...") def crawl_videos(self, user_url, max_count=100): videos = [] self.page.listen.start('aweme/post') self.page.get(user_url) while len(videos) < max_count: self.page.scroll.down(random.randint(300, 800)) time.sleep(random.uniform(0.5, 2)) resp = self.page.listen.wait(timeout=10) if resp and (data := resp.json().get('aweme_list')): videos.extend(data) return videos[:max_count] def download(self, video_list, save_dir): os.makedirs(save_dir, exist_ok=True) for video in video_list: url = video['video']['play_addr']['url_list'][0] title = clean_filename(video['desc'])[:50] # 截断长标题 self._download_with_retry(url, f"{save_dir}/{title}.mp4") def _download_with_retry(self, url, path, max_retries=3): # 实现带重试的下载逻辑 pass

使用示例:

crawler = DouyinCrawler() crawler.login() # 只需登录一次 videos = crawler.crawl_videos('https://www.douyin.com/user/xxx', 200) crawler.download(videos, './videos')

7. 性能优化技巧

在大规模爬取时,还需要考虑效率问题。我总结的几个优化点:

  1. 并发控制:使用多线程处理下载任务
from concurrent.futures import ThreadPoolExecutor with ThreadPoolExecutor(4) as executor: executor.map(download_task, video_list)
  1. 增量爬取:记录已下载视频ID
import json # 保存状态 with open('progress.json', 'w') as f: json.dump({'last_cursor': max_cursor}, f)
  1. 代理轮询:应对IP封禁
proxies = [ 'http://proxy1:port', 'http://proxy2:port' ] proxy = random.choice(proxies) requests.get(url, proxies={'http': proxy})
  1. 数据去重:使用集合存储视频ID
seen_ids = set() if video_id not in seen_ids: seen_ids.add(video_id) # 处理新视频

在实际项目中,我将这些技术组合使用,成功爬取了50个账号的共计1.2万条视频数据。关键是要保持请求频率在合理范围内,我的经验值是每分钟不超过20次请求。

http://www.jsqmd.com/news/658969/

相关文章:

  • Xshell8和Xftp8免费版下载及安装(详细教程)
  • Element UI表格selectable属性:实现动态行选择的业务逻辑
  • 告别上架难题:合规获取IMEI、设备ID等用户信息的原生弹窗实践
  • 为什么《蔚蓝》的剧情插入不让人反感?给独立开发者的叙事节奏设计课
  • 从‘攻防’游戏到模型鲁棒性:深入浅出图解对抗训练中的FGM、PGD与FreeLB
  • Cursor Pro完全免费指南:3步突破AI编程助手限制的终极解决方案
  • FPGA驱动SPI Flash的读写时序与Verilog实现
  • 从命令行到C++代码:手把手教你用OpenSSL 1.1.1实现AES-CBC文件加密与解密
  • 20个现代Web UI组件原型完全指南:打造专业级用户界面
  • FileKit性能优化指南:10个提升文件操作效率的方法
  • 最完整的Vue可视化编辑器方案:OXOYO/X-Flowchart-Vue核心功能与实战指南
  • TorchMetrics与PyTorch Lightning集成:如何实现无代码度量管理
  • Python 字典高效合并:自定义处理重复键的完整指南
  • HJ181 相差不超过k的最多数
  • 低代码平台为何突然“写不出代码”?揭秘AI生成逻辑断层的7个致命信号及48小时修复方案
  • 深入浅出Tcache Attack(一):机制剖析与Poisoning实战
  • django-fsm与Django版本兼容性:从1.8到6.0完整适配
  • FPGA丨高斯滤波算法实现:从理论到硬件架构的平滑之旅
  • 企业培训为什么值得优先上智能体?
  • WMRouter适配器扩展:轻松集成RxJava3与Kotlin协程的终极指南
  • 2026年3月涂胶设备生产厂家推荐,55加仑压盘泵/PACK涂胶机/压盘泵供胶系统/螺杆阀,涂胶设备实力厂家口碑推荐 - 品牌推荐师
  • 【权威实测】生成式AI通信方案吞吐量排行榜:SSE vs Websocket vs gRPC-Web vs QUIC-HTTP/3(TPS/首字节延迟/错误率三维打分)
  • 从零构建企业级流程图引擎:OXOYO/X-Flowchart-Vue 架构解密与实战指南
  • 第 26 课:任务表格列配置与持久化
  • 题解:洛谷 P1554 梦中的统计
  • 彻底搞懂NuGetForUnity架构设计:Unity包管理器核心原理与工作流程解析
  • STC89C51单片机驱动RC522读卡器,手把手教你实现门禁卡识别(附完整代码)
  • 奇点倒计时187天:2026大会AI重构建议的“不可逆窗口期”详解——错过这波,下一轮技术红利至少延迟3.2年
  • TorchMetrics部署指南:从开发到生产环境的完整流程
  • 从零开始:Carbon测试驱动开发实战指南