最新业务需要 研究了一周时间做出来了 可以配合心跳包 做抖音人气用
一下部分代码
# -*- encoding: utf-8 -*-
import json, random, time, sys
import requests
from urllib.parse import urlparse, parse_qs
import ratelimit
from loguru import logger
from spiders.reg.conf import mobile, cfg
from face import get_sixflurl
def schema_trans(surl, isprint=False):
headers = {
"Host": "aweme.snssdk.com",
"sdk-version": "2",
"passport-sdk-version": "17",
"x-ss-req-ticket": str(int(time.time() * 1000)),
"user-agent": "okhttp/3.10.0.1"
}
cookies = {
"store-region": "cn-bj",
"store-region-src": "did",
"odin_tt": cfg.config.get("odin_tt_cookie", ""),
"install_id": cfg.config.get("install_id", ""),
"ttreq": cfg.config.get("ttreq_cookie", ""),
"MONITOR_WEB_ID": cfg.config.get("monitor_web_id", "")
}
url = "https://aweme.snssdk.com/aweme/v1/schema/trans/"
params = {
"url": surl,
"device_id": cfg.config.get("device_id", ""),
"os_version": "13.6",
"iid": cfg.config.get("iid", ""),
"app_name": "aweme",
"version_code": "12.8.0",
"channel": "App Store",
"os_api": "18",
"device_platform": "iphone",
"device_type": "iPhone9,2",
"aid": "1128",
"package": "com.ss.iphone.ugc.Aweme"
}
headers, url = get_sixflurl(
api=url, params=params, header=headers,
devices={"lanusk": cfg.config.get("lanusk_device", "")},
platform="ios", cell=True
)
resp = requests.get(url, headers=headers, cookies=cookies)
print(resp.text)
if isprint:
print(resp.text)
return resp.json()
def extract_url_params(url):
if not url or not url.startswith("https"):
return {}
parsed = urlparse(url) if "?" in url else urlparse(f"https://www.av.cn/?{url}")
qs = parse_qs(parsed.query)
return {k: v[0] for k, v in qs.items()}
def update_params(params, response):
link_info = response.get('link_info', None)
if link_info:
did = json.loads(link_info).get('d_code', 'MS4wLjABAAAA')
else:
did = 'MS4wLjABAAAA'
iid = str(response['share_user_iid'])
utm_medium = params.get("utm_medium", "ios#android")
uppars = {
'device_id': did,
'iid': iid,
'channel': 'update',
'aid': '1128',
'version_code': 320800,
'version_name': '32.8.0',
'device_type': '2106118C',
'device_brand': 'Xiaomi',
'os_api': 31,
'os_version': '12',
'manifest_version_code': 320801,
'resolution': '2400x1080',
'dpi': 440,
'update_version_code': 32809900,
'host_abi': 'arm64-v8a',
'ua': 'com.ss.android.ugc.aweme/320801 (Linux; U; Android 12; zh_CN; 2106118C; Build/odin-user 12 SKQ1.211006.001 V13.0.8.0.SKMCNXM release-keys;tt-ok/3.12.13.1)',
}
news_pars = {}
share_version = params.get("share_version", None)
if share_version:
if len(share_version) != 6:
share_version = '300301'
a_vs = share_version[:2]
b_vs = share_version[2:4]
c_vs = share_version[4:]
if utm_medium == "ios":
i_mobile = random.choice(mobile.ios_mobile)
uppars = {
"device_id": did,
"iid": iid,
"channel": "App Store",
"aid": params.get("from_aid", "1128"),
"lanusk": params.get("lanusk", ""),
"version_code": f"{a_vs}.{int(b_vs)}.{int(c_vs)}",
"app_version": f"{a_vs}.{int(b_vs)}.{int(c_vs)}",
"device_type": i_mobile["device_model"],
"device_platform": "iphone",
"build_number": f"{a_vs}{int(b_vs)}{int(c_vs)}15",
"resolution": i_mobile["resolution"],
"os_version": i_mobile["os_version"],
"ua": f"Aweme {a_vs}.{int(b_vs)}.{int(c_vs)} rv:{a_vs}{int(b_vs)}{int(c_vs)}15 (iPhone; iOS {i_mobile['os_version']}; zh_CN) Cronet",
"utm_medium": utm_medium
}
return uppars
news_pars["version_name"] = f"{a_vs}.{int(b_vs)}.{int(c_vs)}"
news_pars["version_code"] = share_version
news_pars["manifest_version_code"] = share_version
news_pars["update_version_code"] = f"{a_vs}{int(b_vs)}{int(c_vs)}9900"
news_pars["aid"] = params.get("from_aid", "1128")
if utm_medium == "ios":
i_mobile = random.choice(mobile.ios_mobile)
return {
"device_id": did,
"iid": iid,
"channel": "App Store",
"aid": params.get("from_aid", "1128"),
"lanusk": params.get("lanusk", ""),
"version_code": "29.8.0",
"app_version": "29.8.0",
"device_type": i_mobile["device_model"],
"device_platform": "iphone",
"resolution": i_mobile["resolution"],
"build_number": "298015",
"os_version": i_mobile["os_version"],
"ua": f"Aweme 29.8.0 rv:298015 (iPhone; iOS {i_mobile['os_version']}; zh_CN) Cronet",
"utm_medium": utm_medium
}
a_mobile = random.choice(mobile.android_mobile)
load_mobile = {
'device_type': a_mobile["device_type"],
'device_brand': a_mobile["device_brand"],
'device_manufacturer': a_mobile["device_manufacturer"],
'os_api': a_mobile["os_api"],
'os_version': a_mobile["os_version"],
'resolution': a_mobile["resolution"],
'dpi': int(a_mobile["density_dpi"]),
'host_abi': a_mobile["cpu_abi"],
}
def get_package():
package = "com.ss.android.ugc.aweme"
return package
if share_version:
news_pars["ua"] = f'{get_package()}/{share_version} (Linux; U; Android {a_mobile["os_version"]}; zh_CN; {a_mobile["device_type"]}; Build/{a_mobile["rom_version"]}; Cronet/TTNetVersion:19ef7c44 2024-06-03 QuicVersion:9a4adebb 2024-05-28))'
else:
news_pars["ua"] = f'{get_package()}/320801 (Linux; U; Android {a_mobile["os_version"]}; zh_CN; {a_mobile["device_type"]}; Build/{a_mobile["rom_version"]}; Cronet/TTNetVersion:19ef7c44 2024-06-03 QuicVersion:9a4adebb 2024-05-28))'
uppars.update(news_pars)
uppars.update(load_mobile)
return uppars
def save_trans(dev):
line = json.dumps(dev, ensure_ascii=False)
path = 'trans/options-devices.txt'
try:
with open(path, 'a', encoding='utf-8') as f:
f.write(line + '\n')
except FileNotFoundError:
path = 'spiders/reg/trans/options-devices.txt'
with open(path, 'a', encoding='utf-8') as f:
f.write(line + '\n')
@ratelimit.sleep_and_retry
@ratelimit.limits(calls=100, period=1)
def trans_options(cookie, proxy=None):
"""
发起一次 schema 转换请求,返回参数字典或 None
"""
headers = {
"Host": "v.douyin.com",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Linux; Android 9; LIO-AN00 Build/PQ3B.190801.06281541; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"x-requested-with": "com.android.browser",
"sec-fetch-site": "none",
"sec-fetch-mode": "navigate",
"sec-fetch-user": "?1",
"sec-fetch-dest": "document",
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
# 生成随机短码,构造 URL
sh = ''.join(random.choices(
list('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), k=cfg.config.get("transNum")
))
url = f"{cfg.config.get('transUrl')}{sh}/"
resp = requests.get(url, headers=headers, cookies=cookie,
allow_redirects=False, proxies=proxy)
code = resp.status_code
if code == 444:
logger.error(f"请求返回 444,短码: {sh}")
return None
if code == 443:
logger.warning("返回 443,等待 30 秒后重试")
time.sleep(30)
return None
location = resp.headers.get('Location', '')
params = extract_url_params(location)
if params.get("did") and params.get("iid") and params.get("from_aid") != "6383" and params.get("is_qrcode") != "1":
data = schema_trans(location)
opts = update_params(params, data)
print(f'share_url: {url} | dev = {opts}')
return opts
return None
class UpdateCookies(object):
def __init__(self):
pass
@staticmethod
def get_random_cookie():
globcookies = {}
lenttwid = len('7484c927f9dbe5ebdf4ca4bd230a7a3368526db7ba20004551fac0c72cfb6849')
lensign = len('zIAAAIDCb3QM68NvvTMMXsgAAKdqaaUgeWqKs7sGrAocETp4AgRaLcqWGQ')
sign = '0123456789abcdefqwertyuioplkmnjhnbgfvcdxsaz' + '0123456789abcdefqwertyuioplkmnjhnbgfvcdxsaz'.upper()
__ac_nonce = ''.join([random.choice('0123456789abcdef') for _ in range(len('0647f83ea00dc3852419e'))])
__ac_signature = '_02B4Z6wo00f01wx-' + ''.join([random.choice(sign) for _ in range(lensign)])
globcookies['__ac_nonce'] = __ac_nonce
globcookies['__ac_signature'] = __ac_signature
ttwid = f"1%7CLLGhLwhnTHXmhNSzubHyzl3ZS5h--jAN3_EEE4Z-MEM%7C{int(time.time())}%7C" + ''.join(
[random.choice('0123456789abcdef') for _ in range(lenttwid)])
# ttwid = "1%7CLLGhLwhnTHXmhNSzubHyzl3ZS5h--jAN3_EEE4Z-MEM%7C1681894154%7C" + ''.join([random.choice('0123456789abcdef') for _ in range(lenttwid)])
globcookies['ttwid'] = ttwid
return globcookies
def main():
data_num = cfg.config.get("dataNum")
for i in range(data_num):
cookie = UpdateCookies().get_random_cookie()
opts = trans_options(cookie)
if opts:
save_trans(opts)
else:
logger.info(f"第 {i+1} 次获取失败,继续下一个")
time.sleep(cfg.config.get("interval", 0.1))
if __name__ == '__main__':