返回 Social Auto Upload
export_douyin_cookie.sh
根目录 / export_douyin_cookie.sh
1 #!/bin/bash
2 # export_douyin_cookie.sh
3 # 导出已登录 Chrome 的抖音 cookie 到 douyin_{8位随机字符}.json
4 # 使用 curl 直接调用 Chrome DevTools HTTP API
5
6 set -e
7
8 # 解析参数
9 USERNAME=""
10 while [ $# -gt 0 ]; do
11 case "$1" in
12 --account)
13 USERNAME="$2"
14 shift 2
15 ;;
16 *)
17 echo "用法: $0 --account <用户名>"
18 exit 1
19 ;;
20 esac
21 done
22
23 if [ -z "$USERNAME" ]; then
24 echo "未指定用户名,将使用随机文件名"
25 fi
26
27 DEBUG_PORT=9222
28
29 echo "=========================================="
30 echo " 抖音 Cookie 导出工具"
31 echo "=========================================="
32 echo ""
33
34 # 依赖: curl, python3, websocket-client
35
36 echo "检查 Chrome remote debugging..."
37 RESPONSE=$(curl -s "http://localhost:${DEBUG_PORT}/json" 2>/dev/null) || true
38
39 if ! echo "$RESPONSE" | grep -q "webSocketDebuggerUrl"; then
40 echo "Chrome remote debugging 未运行"
41 echo "请先启动 Chrome: chromium --remote-debugging-port=9222 ..."
42 exit 1
43 fi
44
45 echo "Chrome remote debugging 已运行"
46 echo ""
47 echo "获取抖音 Cookie..."
48
49 USERNAME="$USERNAME" python3 << 'PYEOF'
50 import json
51 import os
52 import uuid
53 import sys
54
55 # Shell 把 USERNAME 作为环境变量传过来, Python 需要显式取
56 USERNAME = os.environ.get('USERNAME', '')
57
58 DEBUG_PORT = 9222
59 if USERNAME:
60 COOKIE_FILE = f"cookies/douyin_{USERNAME}.json"
61 else:
62 COOKIE_FILE = f"cookies/douyin_{uuid.uuid4().hex[:8]}.json"
63
64 def get_douyin_cookies():
65 import urllib.request
66 import websocket
67
68 # 获取页面列表
69 url = f"http://localhost:{DEBUG_PORT}/json"
70 with urllib.request.urlopen(url, timeout=10) as response:
71 pages = json.loads(response.read().decode())
72
73 # 查找抖音创作者页面
74 douyin_page = None
75 for page in pages:
76 page_url = page.get("url", "")
77 if "creator.douyin.com" in page_url:
78 douyin_page = page
79 break
80
81 if not douyin_page:
82 print("未找到抖音创作者平台页面")
83 print("请先在 Chrome 中打开并登录 https://creator.douyin.com")
84 return False
85
86 page_url = douyin_page["url"]
87 ws_url = douyin_page.get("webSocketDebuggerUrl", "")
88
89 print(f"找到页面: {page_url}")
90
91 # 连接到目标页面的 WebSocket
92 print(f"连接页面 WebSocket...")
93 ws = websocket.create_connection(ws_url, timeout=30)
94
95 # 获取所有 Cookie
96 ws.send(json.dumps({"id": 1, "method": "Network.getAllCookies"}))
97 response = json.loads(ws.recv())
98
99 cookies = response.get("result", {}).get("cookies", [])
100
101 # 过滤抖音相关的 cookie
102 douyin_cookies = [
103 c for c in cookies
104 if "douyin.com" in c.get("domain", "") or ".douyin.com" in c.get("domain", "")
105 ]
106
107 print(f"获取到 {len(douyin_cookies)} 个抖音 Cookie")
108
109 if len(douyin_cookies) == 0:
110 print("未获取到任何抖音 Cookie,可能未登录")
111 return False
112
113 # 获取 localStorage (origins)
114 print(f"获取 localStorage...")
115 local_storage_by_origin = {}
116
117 # 获取页面 frame 树
118 ws.send(json.dumps({"id": 2, "method": "Page.getResourceTree"}))
119 resp = json.loads(ws.recv())
120 frames = resp.get("result", {}).get("frameTree", {}).get("childFrames", [])
121 all_frames = [resp.get("result", {}).get("frameTree", {})] + frames
122
123 for frame in all_frames:
124 frame_url = frame.get("url", "")
125 frame_id = frame.get("id", "")
126 if "douyin.com" in frame_url or "bytedance.com" in frame_url:
127 # 执行 JavaScript 获取该 frame 的 localStorage
128 script = """
129 (function() {
130 var result = [];
131 for (var i = 0; i < localStorage.length; i++) {
132 var key = localStorage.key(i);
133 result.push([key, localStorage.getItem(key)]);
134 }
135 return result;
136 })()
137 """
138 ws.send(json.dumps({
139 "id": 3,
140 "method": "Runtime.evaluate",
141 "params": {"expression": script, "contextId": frame.get("id")}
142 }))
143 resp = json.loads(ws.recv())
144 result_eval = resp.get("result", {})
145 if result_eval.get("result", {}).get("type") == "array":
146 items = result_eval.get("result", {}).get("value", [])
147 if items:
148 origin = frame_url.rsplit("/", 2)[0] + "//" + frame_url.split("/")[2]
149 local_storage_by_origin[origin] = items
150
151 # 获取主文档的 localStorage
152 script_main = """
153 (function() {
154 var result = [];
155 try {
156 for (var i = 0; i < localStorage.length; i++) {
157 var key = localStorage.key(i);
158 result.push([key, localStorage.getItem(key)]);
159 }
160 } catch(e) {}
161 return result;
162 })()
163 """
164 ws.send(json.dumps({
165 "id": 4,
166 "method": "Runtime.evaluate",
167 "params": {"expression": script_main}
168 }))
169 resp = json.loads(ws.recv())
170 result_eval = resp.get("result", {})
171 if result_eval.get("result", {}).get("type") == "array":
172 items = result_eval.get("result", {}).get("value", [])
173 if items:
174 origin = page_url.rsplit("/", 2)[0] + "//" + page_url.split("/")[2]
175 local_storage_by_origin[origin] = items
176
177 ws.close()
178
179 # 构建 JSON
180 result = {
181 "cookies": [],
182 "origins": []
183 }
184
185 for c in douyin_cookies:
186 result["cookies"].append({
187 "name": c.get("name", ""),
188 "value": c.get("value", ""),
189 "domain": c.get("domain", ""),
190 "path": c.get("path", "/"),
191 "expires": c.get("expires", -1),
192 "httpOnly": c.get("httpOnly", False),
193 "secure": c.get("secure", True),
194 "sameSite": c.get("sameSite", "Lax")
195 })
196
197 # 添加 origins
198 for origin, items in local_storage_by_origin.items():
199 origin_entry = {
200 "origin": origin,
201 "localStorage": [{"name": name, "value": value} for name, value in items]
202 }
203 result["origins"].append(origin_entry)
204
205 # 保存
206 os.makedirs("cookies", exist_ok=True)
207 with open(COOKIE_FILE, "w", encoding="utf-8") as f:
208 json.dump(result, f, indent=2, ensure_ascii=False)
209
210 print(f"Cookie 已保存到: {COOKIE_FILE}")
211 print("")
212
213 # 打印关键 Cookie
214 key_cookies = ["sessionid", "uid_tt", "ssid", "ttwid"]
215 print("关键 Cookie:")
216 for c in douyin_cookies:
217 if c.get("name") in key_cookies:
218 val = c.get("value", "")
219 if len(val) > 30:
220 val = val[:30] + "..."
221 print(f" {c.get('name')}: {val}")
222
223 return True
224
225 if __name__ == "__main__":
226 if not get_douyin_cookies():
227 sys.exit(1)
228 PYEOF
229
230 echo ""
231 echo "=========================================="
232 echo " 完成!文件已导出为$COOKIE_FILE"
233 echo "=========================================="
233 lines BASH