推特 图片 & 视频 & 文本 下载,以用户名为参数,爬取该用户推文中的图片与视频(含gif)
支持排除转推内容 & 多用户爬取 & 时间范围限制 & 按Tag获取 & 纯文本获取 & 高级搜索 & 评论区下载
EN
This project is strictly for programming learning, academic research, and personal practice.
The intellectual property of all media content (images, videos, etc.) downloaded using this tool belongs to the original authors and the respective platforms. Please respect relevant copyrights.
Users must comply with applicable laws, the target platform's Terms of Service, and relevant copyright regulations. Do not use this tool for malicious scraping, copyright infringement, illegal distribution, or other unlawful activities.
The developer assumes no responsibility for any violations, legal disputes, or direct/indirect losses caused by the improper use of this tool. Use at your own risk.
ZH
本项目仅供编程学习交流、学术研究及个人练习使用。
使用本工具下载的所有媒体内容(图片、视频等)的知识产权均归原作者及所属平台所有,请尊重相关版权。
请勿将本工具及所获取的数据用于恶意抓取、侵权传播或其他违法用途。
开发者不对任何因不当使用本工具而导致的违规行为、法律纠纷或直接/间接损失承担责任。请风险自担。
目前老马加了API的请求次数限制
当程序抛出:Rate limit exceeded
即表示该账号当日的API调用次数已耗尽
if 选择包含转推:
爬完一个用户需要调用的API次数约为:总推数(含转推) / 19
elif 不包含:
会大大减少API调用次数
下载不计入次数
下载内容按 用户/年份/ 组织 (multi 模式, 默认), 每月一个总 md + 两个按媒体类型划分的分文件, 媒体文件分目录存放:
用户/
└── {screen_name}/
└── 年份/ (如 2024/)
├── 2024-01.md 总 md: 该月全部推文条目
├── 2024-01-图片.md 仅图片推文条目 (格式与总 md 一致, 只含图片媒体行)
├── 2024-01-视频.md 仅视频推文条目 (含 📹📹 提示行与封面图链接)
└── 2024-01/ 该月媒体文件目录
├── 图片/ 图片文件
└── 视频/
└── 视频封面/ 视频封面 jpg (与视频文件同名)
- 跨月导航: 每月 md 顶部/底部生成高亮跳转链接
**→→→ [2024-02 图片](2024-02-图片.md) ←←←**; 出现新月份时自动刷新所有文件的链接; 图片/视频分文件各有独立的导航链, 无该类媒体的月份不建文件、链上自动跳过 - 媒体链接: 使用相对路径, 中文不编码, 如
2024-01/图片/xxx.jpg、2024-01/视频/xxx.mp4、封面2024-01/视频/视频封面/xxx.jpg - 视频条目: 一条 📹📹 视频名 📹📹 提示行 + 封面嵌套链接, 点击封面用系统默认播放器打开本地视频
- single 模式: 全部内容写入用户根目录单个 {screen_name}.md, 媒体仍按
年份/月份/图片|视频/存放
| 文件 | 说明 |
|---|---|
main.py |
主程序: 下载指定用户的 图片 & 视频 & 文本, 支持 转推/亮点/喜欢/多用户/时间范围/定时运行/增量同步 |
settings.json |
主程序配置 (cookie、用户列表、下载开关、md 模式等), 每个配置项都有 xxx_info 注释 |
tag_down.py |
按 Tag / 高级搜索下载, 内置文本模式, 万金油工具 |
reply_down.py |
下载评论区 (指定用户或推文链接, 支持批量) |
text_down.py |
指定用户纯文本推文获取 (不下载媒体) |
profile_down.py |
获取用户主页信息 (头像 & banner & 简介) |
migrate_media_split.py |
历史数据迁移脚本: 旧 媒体/ 结构 -> 新 图片/视频/ 结构 (幂等, 支持 --dry-run 预览) |
md_gen.py |
内部模块: Markdown 生成 (single/multi, 三系列分块路由, 跨月导航刷新) |
csv_gen.py |
内部模块: CSV 统计报表生成 (csv_gen/csv_log) |
cache_gen.py |
内部模块: 已下载内容记录 (JSON Lines, 下载成功后才记账) |
media_download.py |
内部模块: 媒体下载内核 (清晰度降级、退避重试、.part 原子落盘、停止信号) |
md_format.py / utils.py / url_utils.py / user_info.py / transaction_generate.py |
内部模块: md 版面契约 / 时间·文件名·cookie·HTTP 公共工具 / URL 转义 / 用户信息 / X-Client-Transaction-ID 生成 |
tests/ |
回归测试: python -m unittest discover -s tests (对应代码审查报告中的缺陷清单) |
md 生成模式 (settings.json, 需 md_output: true)
| 配置 | 说明 |
|---|---|
md_mode |
single: 单个 md 文件; multi: 按月分文件 + 图片/视频分文件 (默认) |
append_mode |
开启: 写入固定文件追加新内容 (新内容在最上方); 关闭: 每次运行生成新文件 |
schedule_time |
定时运行 (HH:MM), 配合 autoSync + append_mode 实现全自动增量更新 |
媒体按类型拆分目录与 图片/视频分文件 md 功能上线前, 历史数据存放在 媒体/ (图片视频混放) 与平级 视频封面/ 目录。迁移脚本一键升级到新结构:
python migrate_media_split.py --dry-run # 先预览将移动/改写/删除的内容, 不落盘 (推荐)
python migrate_media_split.py # 迁移 settings.json save_path 下全部用户
python migrate_media_split.py --user screen_name # 只处理指定用户
python migrate_media_split.py --save-path /path # 指定保存根目录(不读 settings.json)
脚本执行内容:
- 将
媒体/下文件按扩展名移入图片/或视频/; 封面统一移入视频/视频封面/子目录 - 重写总 md 中的媒体链接, 指向新目录
- 从总 md 解析推文条目, 重建 月份-图片.md / 月份-视频.md 并补上跨月导航
脚本幂等, 重复运行无副作用; 已迁移过一半的用户 (封面仍混在 视频/ 根目录) 再次运行会自动归位封面并修正 md 链接; 迁移完成后建议再跑一轮增量下载验证 (或设置 autoSync 自动同步)。
-
2026-09-04 (代码严谨性审查修复, 详见 CODE_REVIEW.md)
- 修复 图片404 时的死循环/无限重试,
orig -> 4096x4096原图降级真正生效; 重试带上限+指数退避 - 修复 multi 模式 图片/视频 分文件混入他类条目、给无该类型媒体的月份建空文件的问题 (md 改为按推文分块路由)
- 修复 "下载失败的文件被永久记为已下载": 缓存改为下载成功后才记账, 存储从 pickle 换成 JSON 并周期落盘
- 媒体下载改
.part+ fsync + 原子改名, kill/磁盘满不再留下"看似完整"的截断文件; compose 增加stop_grace_period: 5m - md 死链修复: 下载彻底失败的媒体在 md 落盘前自动摘除链接行
- reply_down 修复 O(n²) 重复下载 (200 条带图评论从约 2 万次请求降回 200 次) 与
search_advanced配置必崩的问题 - tag_down 重试加上限与退避; 各脚本 CSV 生命周期改为 with/finally, 中途出错不再丢缓冲行、不再泄漏句柄
- text_down 修正 CSV 列语义 (作者列不再大面积为空、回复类推文 URL 不再指向父推); profile_down 不再把错误页存成图片
- 异常处理全面去"哑": cookie 配置错误给出可读提示, API 结构变更有告警而不是静默 0 张, 翻页游标停滞有保护
- 时间/文件名/cookie/HTTP/媒体下载等公共逻辑收敛到
utils.py/md_format.py/media_download.py(原先 7 份stamp2time副本等) - 共享 HTTP 连接池 (每文件一次 TLS 握手 -> run 级复用); 配置读取增加校验与默认值; 支持
TW_COOKIE环境变量注入 cookie - 新增
tests/回归测试套件, 覆盖上述 1.1/1.2/1.3 等已复现缺陷
- 修复 图片404 时的死循环/无限重试,
-
2026-09-03
- 媒体文件按类型分目录存储:
图片/与视频/, 视频封面统一存于视频/视频封面/子目录 (与视频文件同名) - multi 模式每月额外生成 月份-图片.md (仅图片) 与 月份-视频.md (仅视频) 两个分文件, 格式与总 md 一致, 各带独立跨月导航
- 新增 migrate_media_split.py 迁移脚本, 一键升级旧
媒体/+视频封面/结构到新结构 (幂等, 兼容迁移中途状态)
- 媒体文件按类型分目录存储:
-
2026-08-18-二改
- 增加只写入到一个md里面的参数配置,关闭就会像原版一样分开多个md
- 增加定时运行功能,填具体时间,每天都会在这个时间运行
- 增加docker相关文件,可自行构建镜像运行
- 打印输出的日志添加了时间戳,修改了保存本地的文件名,优化了下载过程中的内存占用过大问题。
-
2025-08-09
- 支持获取用户主页内容(头像&banner&简介)--请直接配置profile_down.py文件并运行
-
2025-04-26
- 替换部分失效接口
tag_down reply_down增加X-Client-Transaction-ID校验, 请重新运行pip install -r requirements.txt安装依赖- // 目前生成的
transaction-id仍有小概率失效, 当程序抛出获取数据失败时可以尝试重新运行 - 目前
main text_down似乎未受X-Client-Transaction-ID校验影响 - Reference:
https://github.com/iSarabjitDhiman/XClientTransaction
-
2025-03-03
- 支持下载评论区(指定用户或推文链接)--请直接配置reply_down.py文件并运行
-
2024-05-24
- 按Tag获取支持保存文本内容
-
2024-05-11
-
支持获取纯文本推文--请直接配置text_down.py文件并运行
// (下方有预览) 注意,此功能会大量消耗API次数(参考上方公式),默认排除转推内容
-
-
2024-05-10
-
支持按Tag获取--请直接配置tag_down.py文件并运行
// 保存格式 (下方有预览):. / {#Tag} / {datetime} _ {@username} _ { md5( media_url )[:4] } . { png / mp4 }
-
-
2024-03-09
- 支持记录已下载内容,避免重复下载 (如有问题请发issue)
- 支持自动同步最新内容
-
2024-01-16
- 适配 [ 喜欢(Likes) ] 标签页
-
2024-01-10
- 新增统计数据 [ Favorite, Retweet, Reply ]
-
2024-01-05
- 适配Twieer新标签页 [ 亮点(HighLights) ]
-
2023-12-12
- 适配Twitter新API
-
2023-10-12
- 添加 生成爬取信息 功能
-
2023-10-06
- 添加 时间范围限制 功能
- 统一文件保存格式
- 文件夹:用户id (@后面的)
- 文件:推文日期-[img/vid]_下载计数.文件后缀
-
2023-09-15
- 添加 视频下载 功能
Linux :
git clone https://github.com/caolvchong-top/twitter_download.git
cd twitter_download
pip3 install -r requirements.txt
# 版本口径: Python >= 3.8 (httpx 0.28.1 要求; Docker 镜像基于 3.11, 本地 3.12/3.13/3.14 亦已验证)
运行 :
配置settings.json文件
python3 main.py
# 不想把真实 cookie 写进 settings.json (容易被误提交)? 用环境变量注入, 优先级更高:
TW_COOKIE='auth_token=xxx; ct0=xxx;' python3 main.py
Windows 和上面的一样,配置完setting.json后运行main.py即可
docker自行部署 :
# 命令运行
sudo docker build -t my-twitter-download .
sudo docker run -it --name=my-twitter-download -v "/vol1/1000/docker/twitter_download:/app" my-twitter-download
# 重新构建
docker compose up -d --build
# 部署
docker compose up -d
按Tag下载&高级搜索 --> tag_down.py
下载评论区 --> reply_down.py
指定用户纯文本推文获取 --> text_down.py
指定用户媒体文件获取&转推&亮点&喜欢(只能本人账号)等 --> main.py + settings.json
历史数据目录迁移 --> migrate_media_split.py
其余各种不能解决的需求建议试试tag_down的高级搜索, 或是提交Issue
其实按功能应该叫search_down
对于部分主程序难以实现的需求可以尝试配置tag_down.py的filter来曲线解决:
| 部分例子 |
|---|
| 大批量下载 -> 分批下载 |
| 指定时间范围 |
| 各类关键词搜索/排除 |
| 指定/排除目标用户 |
| 指定大于互动量的推文 |
| 指定推文语言 |
| ...... |
// 配置
tag = '#ヨルクラ'
# 填入tag 带上#号 可留空
_filter = ""
# (可选项) 高级搜索
# 请在 https://x.com/search-advanced 中组装搜索条件,复制搜索栏的内容填入_filter
# 注意,_filter中所有出现的双引号都需要改为单引号或添加转义符 例如 "Monika" -> 'Monika'
# 当tag选项留空时,将尝试以_filter的内容作为文件夹名称
推特高级搜索:https://x.com/search-advanced
实例参考:caolvchong-top#63 (comment) & caolvchong-top#106
↑↑老版本的图,仅效果参考
评论区下载 Reply_down.py
按Tag获取 Tag_down.py
纯文本推文获取(仅文本) Text_down.py
图片下载效果
视频下载效果
生成CSV统计








