能批量下载 X(Twitter)公开视频的 Python 版。核心用的是 yt-dlp,它是一个活跃维护的开源下载器,支持大量站点:
先装环境:
pip install -U yt-dlp
下面是完整脚本说明:
从 C:\xvideo\urls.txt 读取 X 链接,一行一个
下载到 C:\xvideo\downloads
已存在的跳过
失败写入 failed.txt
文件名自动带上发布日期、作者、标题、ID
只适合你有权访问的公开内容。
python代码:
# -*- coding: utf-8 -*-
from pathlib import Path
import yt_dlp
import time
# =========================
# 配置区
# =========================
URL_FILE = Path(r"D:\python\X_downloader\urls.txt")
OUT_DIR = Path(r"D:\python\X_downloader\downloads")
FAILED_FILE = Path(r"D:\python\X_downloader\failed.txt")
# 是否使用浏览器 cookies
USE_BROWSER_COOKIES = False
BROWSER_NAME = "chrome" # chrome / edge / firefox
# 下载间隔
SLEEP_SECONDS = 1
OUT_DIR.mkdir(parents=True, exist_ok=True)
FAILED_FILE.parent.mkdir(parents=True, exist_ok=True)
def read_urls(file_path: Path):
if not file_path.exists():
print(f"链接文件不存在: {file_path}")
return []
lines = file_path.read_text(encoding="utf-8", errors="ignore").splitlines()
urls = []
seen = set()
for line in lines:
u = line.strip()
if not u or u.startswith("#"):
continue
if u not in seen:
seen.add(u)
urls.append(u)
return urls
def append_failed(url: str, reason: str):
with FAILED_FILE.open("a", encoding="utf-8") as f:
f.write(f"{url}\t{reason}\n")
def download_with_format(url, fmt):
ydl_opts = {
"outtmpl": str(OUT_DIR / "%(upload_date)s_%(uploader)s_%(title).120s_%(id)s.%(ext)s"),
"format": fmt,
"noplaylist": True,
"ignoreerrors": False,
"retries": 3,
"fragment_retries": 3,
"continuedl": True,
"overwrites": False,
"nooverwrites": True,
"windowsfilenames": True,
"quiet": False,
}
if USE_BROWSER_COOKIES:
ydl_opts["cookiesfrombrowser"] = (BROWSER_NAME,)
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
def main():
urls = read_urls(URL_FILE)
if not urls:
print("没有读取到任何链接。")
return
print(f"共 {len(urls)} 个链接,开始下载...")
# 不装 ffmpeg 时,优先尝试单文件格式
trial_formats = [
"best[ext=mp4]", # 优先单文件 mp4
"best", # 再退一步,任意单流最佳
]
for i, url in enumerate(urls, 1):
print(f"\n[{i}/{len(urls)}] {url}")
success = False
last_err = ""
for fmt in trial_formats:
try:
print(f"尝试格式: {fmt}")
download_with_format(url, fmt)
success = True
break
except Exception as e:
last_err = str(e).replace("\n", " ")[:500]
print(f"该格式失败: {last_err}")
if not success:
print(f"失败: {last_err}")
append_failed(url, last_err)
time.sleep(SLEEP_SECONDS)
print("\n全部处理完成。")
if __name__ == "__main__":
main()