You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何拦截TikTok移动API请求触发的验证码并完成验证以恢复接口访问

如何拦截TikTok移动API请求触发的验证码并完成验证以恢复接口访问

我在爬取TikTok Shop的时候,因为它仅支持移动端访问,所以尝试调用它的移动API接口,但当发送请求过于频繁时,API会返回如下错误:

{ "code": -9999, "message": "internal error" }

出现这个错误后,我在手机端打开TikTok时会看到验证码验证界面,只有完成验证码验证后,API请求才能恢复正常。

TikTok验证码界面

我观察到验证码的处理流程是这样的:首先会发送一个GET请求到验证码相关地址,接着发送两次GET请求获取验证码图片;验证成功后,会向验证码地址发送一个POST请求,携带一些混淆后的参数。

经过大量测试后我发现,TikTok Shop的商品信息查询API端点仅需要我使用的模拟器的设备ID就能正常工作,这是经过各种Header测试后确认的唯一必填项。现在我需要能通过设备ID来复刻请求,以下是我当前发送请求的代码:

# TikTok Shop商品信息查询API地址
url = "oec19-normal-useast5.tiktokv.us/api/v1/shop/product_info/get"

# 请求参数
params = {
    "device_platform": "android",  # 标识设备平台(Android)
    "os": "android",  # 指定操作系统类型
    "ssmix": "a",  # 应用特定配置参数
    "_rticket": "1735656534122",  # 请求时间戳
    "cdid": "97fad962-8535214354240a836c9555",  # 客户端唯一设备ID
    "channel": "googleplay",  # 应用分发渠道(Google Play商店)
    "aid": "1233",  # TikTok内部应用ID
    "app_name": "musical_ly",  # 应用名称标识
    "version_code": "370903",  # 应用版本代码
    "version_name": "37.9.3",  # 应用版本名称
    "manifest_version_code": "48828923",  # 应用内部清单版本代码
    "update_version_code": "2022049030",  # 应用更新版本代码
    "ab_version": "37.9.3",  # A/B测试版本标识
    "resolution": "1600*900",  # 设备屏幕分辨率
    "dpi": "320",  # 设备屏幕密度
    "device_type": "SM-G998N",  # 设备型号(三星Galaxy S20 Ultra)
    "device_brand": "samsung",  # 设备品牌
    "language": "en",  # 用户语言设置
    "os_api": "22",  # Android系统API级别(对应7.1.2版本)
    "os_version": "7",  # 操作系统版本
    "ac": "wifi",  # 当前网络类型
    "is_pad": "0",  # 是否为平板设备
    "current_region": "US",  # 用户当前所在地区
    "app_type": "normal",  # 应用类型(普通版)
    "sys_region": "FR",  # 系统地区设置
    "last_install_time": "1732924273",  # 应用最后安装时间戳
    "mcc_mnc": "322456",  # 移动国家/网络代码
    "timezone_name": "Africa/Brazzaville",  # 时区名称
    "carrier_region_v2": "300",  # 运营商地区标识
    "residence": "US",  # 用户常驻地区
    "build_number": "36",  # 应用构建版本号
    "uoo": "0",  # 应用特定配置参数
    "carrier_region": "US",  # 运营商地区
    "region": "GB",  # 用户地区标识
    "locale": "en-GB",  # 区域语言设置
    "op_region": "US",  # 服务运营地区
    "content_language": "en,ru,",  # 偏好内容语言
    "timezone_offset": "3600",  # 时区偏移(秒)
    "ts": "1735654933",  # 请求时间戳
    "app_language": "en",  # 应用内语言设置
    "ac2": "wifi",  # 备用网络类型
    "host_abi": "arabi-v7a",  # 设备CPU架构
    "iid": "3435643",  # 应用安装唯一ID
    "device_id": "42424492482942",  # 核心设备唯一ID(模拟器设备ID)
    "openudid": "39448Dd",  # 开放设备唯一ID
}

# 请求头信息
second_headers = {
    "Accept-Encoding": "gzip",
    "Connection": "Keep-Alive",
    "Content-Length": "1785",
    "Content-Type": "application/json; charset=UTF-8",
    "Host": "oec19-normal-useast5.tiktokv.us",
    "oec-vc-sdk-version": "3.0.5.i18n",
    "passport-sdk-version": "6033840",
    "rpc-persist-pyxis-policy-v-tnc": "1",
    "sdk-version": "2",
    "User-Agent": "com.zhiliaoapp.musically/2023709030 (Linux; U; Android 7.1.2; en_GB; SM-G988N; Build/NRD90M;tt-ok/3.12.13.16)",
    "X-Argus": "o+HE69eMgMQi0mtZTKUey6LXbWNId2zPIoTaWuPSQTfU4kXQD+m/5wjIB4KlyqGeLTYZpaqC4Z4hWArBznJ9TEWlAFv8gYMOzVvp/bQmLiKXobtMgfUqo8j3D0Ls3a/oTjhSIzd/JISpmf4ZFXYbR5QHk7mRqxJhedbT00suLyLDUHqIH0sIph7IovnI603LHJ1oDjSPnK51txrWYCTEH3J04d7z8WavsFOH+TdJflHIPLB8F0lmTwookUrV7tlNcJ80mcY8o7Jc83kmkwixhr6XJ77XCNk8eLELUV4VKXfZZteEJPo2XoQ9LG8zRkGF1zy4KG4Cf4bFQVGVcGng8yUhJ/wpJBahw2hR/QEI8AuchtPEwCuMFo7eID46mGMLuLCIiobxMfq+d6HiY1cUZXV6OfI5lJz7L5zB8In2WXDMIfDj5kCC0vLO77/7NEgOStoZAk7DQgekYNnUCRGHfbPI7Z/hW/tEXPofRg6sV1YTNY5KOxVlDG4wgUDP4Y8XKR+vRMtJ/yQnOj3S7JvzJbYFFJZoG8yrrzcXFfWga7wCJCozzPQDq6JWiu6bZ1Y7oFq9xey55eeqbw4U/VX0xUMOKqptdUYnKbVB0cXuDySKQ=",
    "x-bd-client-key": "#gL3JJ3JDNXS2Pc4QLPLvtNfliviDO+MNs07QbaVrHBg8iVVN",
    "x-bd-kmsv": "0",
    "X-Gorgon": "0404401040010bdd2fe8d7c93a42c35223a65",
    "X-Khronos": "4442484",
    "X-Ladon": "M/oMR2344QLz95ntHX74Vm8glLwbVpf",
    "X-SS-REQ-TICKET": "17356575TY3",
    "X-SS-STUB": "14772E37DDDZSCD33253535D58A2E3564",
    "x-tt-dm-status": "login=0;ct=0;rt=0",
    "x-tt-pba-enable": "1",
    "x-tt-request-tag": "n=0;nr=011;bg=0",
    "x-tt-store-region": "us",
    "x-tt-store-region-src": "us",
    "X-Tt-Token": "0408b4f30f13360e7c6c08c81a29ecaba232fbdeeefeif33djDNJDdcdc18f657390484e1387bb6dc036620b92fe47f7052bfbc6ef0769ddca35075b6793ae7-CkBkMDdhM2Q4M2VkNWI5NGYxYzllODc3M2NmOTQxZjU4Mzk4NGRjMWUyZWZhYjM4NzRmNWE4YjI0ZWViMDg5NWU0-2.0.0",
    "x-vc-bdturing-sdk-version": "2.3.8.i18n"
}

# 请求体数据
second_case = {
  "request_scene": 1,
  "product_id": [
    "1729601859019968807"
  ],
  "should_use_ocp": 0,
  "page_source_info": "{\"ec_head\":{\"extra\":{\"ec_is_video_page\":\"0\"},\"page_name\":\"b2001\"},\"page_source_list\":[{\"extra\":{\"ec_is_video_page\":\"0\"},\"page_name\":\"b2001\"},{\"extra\":{\"traffic_diversion_info\":\"{\\\"traffic_out_source\\\":\\\"homepage_top_2tab.in_app\\\",\\\"traffic_material_id\\\":\\\"\\\",\\\"traffic_campaign_id\\\":\\\"\\\",\\\"traffic_track_id\\\":\\\"1735656518216\\\",\\\"mall_btm\\\":\\\"a2270.b0865.c8938.d9932_i18\\\",\\\"mall_bcm\\\":\\\"|||\\\"}\",\"feed_tab\":\"0|0\",\"prefix_ec_params_origin_is_mall_tab\":\"homepage_mall\",\"bcm_feed_tab\":\"0\",\"bcm_nova_delivery_id\":\"nd202412311505067277000000000000104609958221062\",\"ec_next_page_c_btm_code\":\"c8938\",\"ec_next_page_d_btm_code\":\"d9932_i18\"},\"page_name\":\"b0865\"},{\"page_name\":\"b6661\"}]}",
  "biz_template": 3,
  "promotion_response_style": 1,
  "traffic_signature": "{\"scene\":\"Default.Western_Mall.Homepage_Feeds.Common\"}",
  "kol_id": "7495541563206240551",
  "template": "tt_pdp_full",
  "product_enter_context": {
    "1729601859019968807": {
      "req_type": 1,
      "is_from_selection_scenarios": False
    }
  },
  "experiment": {
    "param": {
      "ecom_logistic_display_opt": 1,
      "display_history_shipday": 1,
      "ecom_pdp_folding_display": 1,
      "is_new_pdp_logistic_module": 1,
      "is_new_pdp_sales_count_text": 1,
      "segregate_review_list": 1,
      "pdp_promo_cx_optimization": 0,
      "pdp_desc_layout_improve": 1
    },
    "params_map": {
      "logistic_move_up_config": "{}",
      "pdp_first_screen_opt_config": "{\"full_pdp_header_to_top\":false,\"has_label_floor\":false,\"promotion_and_waist_up\":false,\"half_pdp_shorten_height\":false,\"base_ui_change\":false}"
    }
  },
  "preselect_spec_ids": [],
  "traffic_source_list": [
    6
  ],
  "product_source_info": {
    "1729601859019968807": 6
  },
  "ship_to_addr": []
}

我现在的核心需求是:当触发验证码限制后,能够模拟完成验证码验证的流程,让对应的设备ID恢复API访问权限,或者直接通过设备ID复刻出可正常访问的请求。


备注:内容来源于stack exchange,提问作者Kirada

火山引擎 最新活动