重构为 HTTP SSO 扫码方案并引入 Vue3 前端
移除 Playwright 浏览器自动化,改用 passport/SSO HTTP 接口获取二维码与轮询登录;后端模块化拆分,前端替换为 Vue3 SPA。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
|
||||
headers = {
|
||||
"User-Agent": UA,
|
||||
"Referer": "https://www.douyin.com/",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Origin": "https://www.douyin.com",
|
||||
}
|
||||
s = requests.Session()
|
||||
reg = s.post(
|
||||
"https://ttwid.bytedance.com/ttwid/union/register/",
|
||||
json={
|
||||
"region": "cn",
|
||||
"aid": 1768,
|
||||
"needFid": False,
|
||||
"service": "www.douyin.com",
|
||||
"migrate_info": {"ticket": "", "source": "web"},
|
||||
"cbUrlProtocol": "https",
|
||||
"union": True,
|
||||
},
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
).json()
|
||||
cb = reg.get("redirect_url")
|
||||
if cb:
|
||||
s.get(cb, headers=headers, timeout=15, allow_redirects=True)
|
||||
s.get("https://www.douyin.com/", headers=headers, timeout=15)
|
||||
s.get("https://www.douyin.com/passport/web/login/", headers=headers, timeout=15)
|
||||
print("cookies", [c.name for c in s.cookies])
|
||||
try:
|
||||
rr = s.get("https://www.douyin.com/passport/web/csrf/token/", headers=headers, timeout=10)
|
||||
print("csrf", rr.status_code, rr.text[:200])
|
||||
except Exception as e:
|
||||
print("csrf err", e)
|
||||
ts = int(time.time() * 1000)
|
||||
tests = [
|
||||
("sso", "https://sso.douyin.com/get_qrcode/", {"aid": "6383", "service": "https://www.douyin.com", "is_vcd": "1", "t": ts}),
|
||||
("passport", "https://www.douyin.com/passport/web/get_qrcode/", {"aid": "6383", "service": "https://www.douyin.com", "need_logo": "false", "t": ts}),
|
||||
("creator", "https://sso.douyin.com/get_qrcode/", {"aid": "2906", "next": "https://creator.douyin.com", "service": "https://creator.douyin.com", "is_vcd": "1", "t": ts}),
|
||||
]
|
||||
for name, url, params in tests:
|
||||
r = s.get(url, params=params, headers=headers, timeout=15)
|
||||
ct = r.headers.get("content-type", "")
|
||||
print("---", name, r.status_code, ct)
|
||||
print(r.text[:400])
|
||||
@@ -0,0 +1,45 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
|
||||
|
||||
def try_flow(referer, service, aid, next_url=None):
|
||||
headers = {
|
||||
"User-Agent": UA,
|
||||
"Referer": referer,
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Origin": referer.rstrip("/"),
|
||||
}
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
"https://ttwid.bytedance.com/ttwid/union/register/",
|
||||
json={
|
||||
"region": "cn",
|
||||
"aid": 1768,
|
||||
"needFid": False,
|
||||
"service": "www.douyin.com",
|
||||
"migrate_info": {"ticket": "", "source": "web"},
|
||||
"cbUrlProtocol": "https",
|
||||
"union": True,
|
||||
},
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
)
|
||||
s.get(referer, headers=headers, timeout=15)
|
||||
ts = int(time.time() * 1000)
|
||||
params = {"aid": str(aid), "service": service, "is_vcd": "1", "t": ts}
|
||||
if next_url:
|
||||
params["next"] = next_url
|
||||
r = s.get("https://sso.douyin.com/get_qrcode/", params=params, headers=headers, timeout=15)
|
||||
print("===", referer, aid, r.status_code, r.headers.get("content-type"))
|
||||
if "json" in (r.headers.get("content-type") or ""):
|
||||
print(r.text[:500])
|
||||
else:
|
||||
print(r.text[:100])
|
||||
|
||||
for ref, svc, aid, nxt in [
|
||||
("https://creator.douyin.com/", "https://creator.douyin.com", 2906, "https://creator.douyin.com"),
|
||||
("https://www.douyin.com/", "https://www.douyin.com", 6383, None),
|
||||
("https://www.douyin.com/", "https://www.douyin.com", 1128, "https://www.douyin.com"),
|
||||
]:
|
||||
try_flow(ref, svc, aid, nxt)
|
||||
@@ -0,0 +1,66 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
|
||||
|
||||
s = requests.Session()
|
||||
base_headers = {
|
||||
"User-Agent": UA,
|
||||
"Referer": "https://www.douyin.com/",
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Origin": "https://www.douyin.com",
|
||||
}
|
||||
|
||||
s.post(
|
||||
"https://ttwid.bytedance.com/ttwid/union/register/",
|
||||
json={
|
||||
"region": "cn",
|
||||
"aid": 1768,
|
||||
"needFid": False,
|
||||
"service": "www.douyin.com",
|
||||
"migrate_info": {"ticket": "", "source": "web"},
|
||||
"cbUrlProtocol": "https",
|
||||
"union": True,
|
||||
},
|
||||
headers=base_headers,
|
||||
timeout=15,
|
||||
)
|
||||
s.get("https://www.douyin.com/", headers=base_headers, timeout=15)
|
||||
s.get("https://www.douyin.com/passport/web/login/", headers=base_headers, timeout=15)
|
||||
|
||||
csrf = None
|
||||
for c in s.cookies:
|
||||
if c.name == "passport_csrf_token":
|
||||
csrf = c.value
|
||||
break
|
||||
print("passport_csrf_token", csrf)
|
||||
print("all cookies", [(c.name, c.domain) for c in s.cookies])
|
||||
|
||||
ts = int(time.time() * 1000)
|
||||
params = {
|
||||
"aid": "6383",
|
||||
"service": "https://www.douyin.com",
|
||||
"need_logo": "false",
|
||||
"is_vcd": "1",
|
||||
"t": str(ts),
|
||||
}
|
||||
headers = dict(base_headers)
|
||||
if csrf:
|
||||
headers["x-tt-passport-csrf-token"] = csrf
|
||||
|
||||
for method in ("GET", "POST"):
|
||||
if method == "POST":
|
||||
r = s.post(
|
||||
"https://www.douyin.com/passport/web/get_qrcode/",
|
||||
params=params,
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
)
|
||||
else:
|
||||
r = s.get(
|
||||
"https://www.douyin.com/passport/web/get_qrcode/",
|
||||
params=params,
|
||||
headers=headers,
|
||||
timeout=15,
|
||||
)
|
||||
print(method, r.status_code, r.text[:500])
|
||||
Reference in New Issue
Block a user