Skip to content

Commit 0ac2702

Browse files
committed
💥将XB计算单独放入Server目录并添加启动、打包命令
1 parent 67b4a11 commit 0ac2702

File tree

13 files changed

+464
-6
lines changed

13 files changed

+464
-6
lines changed

Server/Server.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
'''
4+
@Description:Server.py
5+
@Date :2023/02/25 17:03:32
6+
@Author :JohnserfSeed
7+
@version :0.0.1
8+
@License :MIT License
9+
@Github :https://github.com/johnserf-seed
10+
@Mail :johnserf-seed@foxmail.com
11+
-------------------------------------------------
12+
Change Log :
13+
2023/02/25 17:03:32 - Create Flask Server XB Gen
14+
2023/08/03 16:48:34 - Fix ttwid
15+
-------------------------------------------------
16+
'''
17+
18+
import time
19+
import execjs
20+
# import sqlite3
21+
import requests
22+
23+
from flask import Flask
24+
from flask import request
25+
from flask import jsonify
26+
# from flask import make_response
27+
# from flask import render_template
28+
29+
from urllib.parse import urlencode
30+
from urllib.parse import unquote
31+
from urllib.parse import parse_qsl
32+
33+
class Server:
34+
def __init__(self) -> None:
35+
# 工厂模式
36+
self.app = Flask(__name__)
37+
38+
self.app.config.from_mapping(
39+
SECRET_KEY='douyin-xbogus'
40+
)
41+
42+
self.app.config['JSON_AS_ASCII'] = False
43+
44+
with open("x-bogus.js", "r", encoding="utf-8") as fp:
45+
self.xbogust_func = execjs.compile(fp.read())
46+
47+
with open("x-tt-params.js", "r", encoding="utf-8") as fp:
48+
self.xttm_func = execjs.compile(fp.read())
49+
50+
self.ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
51+
52+
# 获取xg参数
53+
def getXG(self, url_path, params):
54+
xbogus = self.xbogust_func.call("getXB", url_path)
55+
# 字典中添加xg
56+
params["X-Bogus"] = xbogus
57+
tips = {
58+
"status_code": "200",
59+
"time": {
60+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
61+
"timestamp": int(round(time.time() * 1000))
62+
},
63+
"result": [{
64+
"params": params,
65+
"paramsencode": urlencode(params, safe="="),
66+
"user-agent": self.ua,
67+
"X-Bogus": {
68+
0: xbogus,
69+
1: "X-Bogus=%s" % xbogus
70+
}
71+
}]
72+
}
73+
print(tips)
74+
return jsonify(tips)
75+
76+
# 生成x-tt-params
77+
def getxttparams(self, url_path):
78+
xttp = self.xttm_func.call("getXTTP", url_path)
79+
tips = {
80+
"status_code": "200",
81+
"time": {
82+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
83+
"timestamp": int(round(time.time() * 1000))
84+
},
85+
"result": [{
86+
"headers": {
87+
"user-agent": self.ua,
88+
"x-tt-params": xttp
89+
}
90+
}]
91+
}
92+
print(tips)
93+
return jsonify(tips)
94+
95+
def gen_ttwid(self) -> str:
96+
"""生成请求必带的ttwid
97+
param :None
98+
return:ttwid
99+
"""
100+
url = 'https://ttwid.bytedance.com/ttwid/union/register/'
101+
data = '{"region":"cn","aid":1768,"needFid":false,"service":"www.ixigua.com","migrate_info":{"ticket":"","source":"node"},"cbUrlProtocol":"https","union":true}'
102+
response = requests.request("POST", url, data=data)
103+
# j = ttwid k = 1%7CfPx9ZM.....
104+
for j, k in response.cookies.items():
105+
tips = {
106+
"status_code": "200",
107+
"time": {
108+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
109+
"timestamp": int(round(time.time() * 1000))
110+
},
111+
"result": [{
112+
"headers": {
113+
"user-agent": self.ua,
114+
"cookie": "ttwid=%s;" % k
115+
}
116+
}]
117+
}
118+
print(tips)
119+
return jsonify(tips)
120+
121+
122+
if __name__ == "__main__":
123+
server = Server()
124+
# 首页
125+
@server.app.route('/', methods=['GET', 'POST'])
126+
def index():
127+
tips = {
128+
"status_code": "-1",
129+
"time": {
130+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
131+
"timestamp": int(round(time.time() * 1000))
132+
},
133+
"path": {
134+
0: "/xg/path/?url=",
135+
2: "/x-tt-params/path"
136+
}
137+
}
138+
print(tips)
139+
return jsonify(tips)
140+
141+
# xg参数
142+
@server.app.route('/xg/path/', methods=['GET', 'POST'])
143+
def xgpath():
144+
path = request.args.get('url', '')
145+
# 如果str路径为空
146+
if not path:
147+
tips = {
148+
"status_code": "-3",
149+
"time": {
150+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
151+
"timestamp": int(round(time.time() * 1000))
152+
},
153+
"message": {
154+
0: "The key url cannot be empty and the need for url encoding, The '&' sign needs to be escaped to '%26', Use urllib.parse.quote(url) to escape. Example:/xg/path/?url=aid=6383%26sec_user_id=xxx%26max_cursor=0%26count=10",
155+
1: "url参数不能为空,且需要注意传入值中的“&”需要转义成“%26”,使用urllib.parse.quote(url)转义. 例如:/xg/path/?url=aid=6383%26sec_user_id=xxx%26max_cursor=0%26count=10"
156+
}
157+
}
158+
print(tips)
159+
return jsonify(tips)
160+
else:
161+
# url转字典
162+
params = dict(parse_qsl(path))
163+
# 字典转url
164+
url_path = urlencode(params, safe="=")
165+
return server.getXG(url_path, params)
166+
167+
# x-tt-params参数
168+
@server.app.route('/x-tt-params/path', methods=['GET', 'POST'])
169+
def xttppath():
170+
try:
171+
path = request.json
172+
except:
173+
pass
174+
if not path:
175+
tips = {
176+
"status_code": "-5",
177+
"time": {
178+
"strftime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
179+
"timestamp": int(round(time.time() * 1000))
180+
},
181+
"message": {
182+
0: "Body uses raw JSON format to pass dictionary parameters, such as %s" % '{"aid": 1988,"app_name": "tiktok_web","channel": "tiktok_web".........}',
183+
1: "body中使用raw json格式传递字典参数,如%s" % '{"aid": 1988,"app_name": "tiktok_web","channel": "tiktok_web".........}'
184+
}
185+
}
186+
print(tips)
187+
return jsonify(tips)
188+
else:
189+
return server.getxttparams(path)
190+
191+
# ttwid
192+
@server.app.route('/xg/ttwid', methods=['GET', 'POST'])
193+
def ttwid():
194+
return server.gen_ttwid()
195+
196+
197+
server.app.run(host='0.0.0.0',port='8889')

Server/Server.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# UTF-8
2+
#
3+
# For more details about fixed file info 'ffi' see:
4+
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
5+
VSVersionInfo(
6+
ffi=FixedFileInfo(
7+
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
8+
# Set not needed items to zero 0.
9+
filevers=(1, 4, 2, 2),
10+
prodvers=(1, 4, 2, 2),
11+
# Contains a bitmask that specifies the valid bits 'flags'r
12+
mask=0x3f,
13+
# Contains a bitmask that specifies the Boolean attributes of the file.
14+
flags=0x0,
15+
# The operating system for which this file was designed.
16+
# 0x4 - NT and there is no need to change it.
17+
OS=0x40004,
18+
# The general type of file.
19+
# 0x1 - the file is an application.
20+
fileType=0x1,
21+
# The function of the file.
22+
# 0x0 - the function is not defined for this fileType
23+
subtype=0x0,
24+
# Creation date and time stamp.
25+
date=(0, 0)
26+
),
27+
kids=[
28+
StringFileInfo(
29+
[
30+
StringTable(
31+
u'080404b0',
32+
[StringStruct(u'CompanyName', u'JohnserfSeed'),
33+
StringStruct(u'FileDescription', u'本地解析服务'),
34+
StringStruct(u'FileVersion', u'1.4.2.2'),
35+
StringStruct(u'LegalCopyright', u'Copyright (C) 2019-2023 JohnserfSeed. All Rights Reserved'),
36+
StringStruct(u'ProductName', u'本地解析服务'),
37+
StringStruct(u'ProductVersion', u'1.4.2.2')])
38+
]),
39+
VarFileInfo([VarStruct(u'Translation', [2052, 1200])])
40+
]
41+
)

Server/build-win.bat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@echo off
2+
echo Install Npm Require
3+
npm i
4+
echo Install Pip Require
5+
pip install -r requirements.txt
6+
echo Build EXE version, Press Ctrl + C to Exit
7+
echo Build Server
8+
pyinstaller -F -i f2-logo.ico --version-file Server.txt --hidden-import=charset_normalizer.md__mypyc Server.py
9+
pause

Server/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"dependencies": {
3+
"crypto-js": "^4.1.1",
4+
"md5": "^2.3.0"
5+
}
6+
}

Server/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask==2.2.5
2+
PyExecJS==1.5.1

Server/s_v_web_id.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function create_s_v_web_id() {
2+
var e = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("")
3+
, t = e.length
4+
, n = (new Date).getTime().toString(36)
5+
, r = [];
6+
7+
r[8] = r[13] = r[18] = r[23] = "_",
8+
r[14] = "4";
9+
for (var o, i = 0; i < 36; i++)
10+
r[i] || (o = 0 | Math.random() * t,
11+
r[i] = e[19 == i ? 3 & o | 8 : o]);
12+
return "verify_" + n + "_" + r.join("")
13+
}
14+
15+
console.log(create_s_v_web_id())

Server/s_v_web_id.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import time
2+
import random
3+
4+
def create_s_v_web_id():
5+
e = list("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
6+
t = len(e)
7+
n = base36_encode(int(time.time()*1000)) # Convert timestamp to base 36
8+
9+
r = [''] * 36
10+
r[8] = r[13] = r[18] = r[23] = "_"
11+
r[14] = "4"
12+
13+
for i in range(36):
14+
if not r[i]:
15+
o = int(random.random() * t)
16+
r[i] = e[3 & o | 8 if i == 19 else o]
17+
18+
return "verify_" + n + "_" + "".join(r)
19+
20+
def base36_encode(number):
21+
"""Converts an integer to a base36 string."""
22+
alphabet = '0123456789abcdefghijklmnopqrstuvwxyz'
23+
base36 = []
24+
25+
while number:
26+
number, i = divmod(number, 36)
27+
base36.append(alphabet[i])
28+
29+
return ''.join(reversed(base36))
30+
31+
print(create_s_v_web_id())

0 commit comments

Comments
 (0)