最新 抖音 iOS 设备注册算法(配合心跳做不上榜人气用)

最新业务需要   研究了一周时间做出来了  可以配合心跳包  做抖音人气用

一下部分代码

# -*- 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__':
 
 

你可能感兴趣的:(ios,算法,cocoa)