mirror of
https://github.com/wahyd4/by-agent-for-agent.git
synced 2026-08-09 05:16:01 +10:00
74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
# /// script
|
|
# requires-python = ">=3.12"
|
|
# dependencies = [
|
|
# "httpx",
|
|
# ]
|
|
# ///
|
|
import httpx
|
|
import re
|
|
import os
|
|
import sys
|
|
|
|
def download_twitter_photo_nitter(url, output_dir="downloads"):
|
|
if not os.path.exists(output_dir):
|
|
os.makedirs(output_dir)
|
|
|
|
# 提取推文 ID
|
|
match = re.search(r'status/(\d+)', url)
|
|
if not match:
|
|
print("❌ 无法提取推文 ID")
|
|
return
|
|
tweet_id = match.group(1)
|
|
|
|
# 使用 Nitter 镜像站绕过限制(这是目前 Docker 环境最稳的方法)
|
|
# Nitter 实例列表可以替换,如果这个挂了可以换另一个
|
|
nitter_instances = ["https://nitter.net", "https://nitter.cz", "https://nitter.moomoo.me"]
|
|
|
|
headers = {
|
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
}
|
|
|
|
success = False
|
|
for instance in nitter_instances:
|
|
try:
|
|
nitter_url = f"{instance}/i/status/{tweet_id}"
|
|
print(f"🕵️ 尝试通过镜像站抓取: {nitter_url}")
|
|
|
|
with httpx.Client(headers=headers, follow_redirects=True, timeout=20.0) as client:
|
|
response = client.get(nitter_url)
|
|
if response.status_code != 200:
|
|
continue
|
|
|
|
# 寻找图片链接 (Nitter 的图片通常是 /pic/media%2F...)
|
|
# 示例正则匹配
|
|
img_paths = re.findall(r'/pic/media%2F[^"]+', response.text)
|
|
if not img_paths:
|
|
# 尝试另一种匹配
|
|
img_paths = re.findall(r'/pic/orig/media%2F[^"]+', response.text)
|
|
|
|
if img_paths:
|
|
for i, path in enumerate(set(img_paths)):
|
|
full_img_url = f"{instance}{path}"
|
|
print(f"📥 发现图片: {full_img_url}")
|
|
|
|
img_res = client.get(full_img_url)
|
|
if img_res.status_code == 200:
|
|
save_path = os.path.join(output_dir, f"tweet_{tweet_id}_{i}.jpg")
|
|
with open(save_path, "wb") as f:
|
|
f.write(img_res.content)
|
|
print(f"✅ 保存成功: {save_path}")
|
|
success = True
|
|
|
|
if success: break # 下载到就停
|
|
except Exception as e:
|
|
print(f"⚠️ 尝试实例 {instance} 时出错: {e}")
|
|
|
|
if not success:
|
|
print("❌ 所有尝试均失败。可能镜像站也无法访问该推文,或该推文是私密的。")
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("用法: uv run scripts/twitter_dl_v2.py <url>")
|
|
else:
|
|
download_twitter_photo_nitter(sys.argv[1])
|