某宝x-sign签名分析-店铺全量商品接口

接上篇。

店铺全量商品接口测试 - 9.x版本,需要x-sign和x-miniwua,8.x 版本该接口不可用:

# -*- coding: utf-8 -*-

import time
from typing import Dict
import requests

import json
from urllib.parse import quote


def timer(function):
    def wrapper(*args, **kwargs):
        time_start = time.time()
        res = function(*args, **kwargs)
        cost_time = time.time() - time_start
        print("【%s】运行时间:【%s】秒" % (function.__name__, cost_time))
        return res

    return wrapper


def dict_encode(param_dict):
    return json.dumps(param_dict, separators=(',', ':'))


class TBBaseClass():

    xsign_url = "xxxxxx"    # 测试链接,如需测试,请联系QQ获取。+Q: 251273504
    serverg = "tb910"
    servera = "tbxsign"

    def random_lat_lng(self):
        return {"lng": "0", "lat": "0"}

    def random_device_info(self):
        device_info = {
            "user-agent": 'Dalvik/2.1.0 (Linux; U; Android 8.1.0; Xiaomi 8 Build/OPM1.171019.011)',
            # "deviceId": 'xxxx',
            "appKey": "21646297",
            # "utdid": 'xxxxxxx',
            "ttid": "1628000524142@taobao_android_9.1.0",
        }
        return device_info

    def get_xsign(self, params):
        params["group"] = self.serverg
        params["action"] = self.servera
        try:
            response = requests.post(
                self.xsign_url,
                json=params,
                verify=False,
                timeout=3
            )
            res = response.json()
            result = res["data"]
            if "x-sign" not in result.keys():
                print({'error': f'调用x-sign接口失败., result: {result}'})
                return None
            return result
        except Exception as e:
            import traceback
            traceback.print_exc()
            print({'error': f'调用x-sign接口异常. {e}'})
            return None

    @staticmethod
    def get_header(params, x_sign_data):
        headers = {
            "x-features": params.get("x-features"),
            "x-pv": "6.3",
            "x-sgext": "923",
            "x-location": ",".join([params.get("lng"), params.get("lat")]),
            "user-agent": params.get("user-agent"),  # quote(params.get("user-agent"), safe="+"),
            "x-ttid": params.get("ttid"),
            "x-appkey": params.get("appKey"),
            "x-devid": params.get("deviceId"),
            "x-utdid": params.get("utdid"),
            "x-t": params.get("timestamp")[:10],
            "x-uid": params.get("uid"),
            "x-sid": params.get("sid"),
            "x-umt": quote(x_sign_data.get("x-umt"), safe=''),
            "x-mini-wua": quote(x_sign_data.get("x-mini-wua"), safe=''),
            "x-sign": quote(x_sign_data.get("x-sign"), safe=''),
            'x-bx-version': '6.4.11',
            # 'f-refer': 'mtop',
            # 'x-app-ver': '9.1.0',
            'user-agent': 'MTOPSDK%2F3.1.1.7+%28Android%3B8.1.0%3BXiaoMi%3BXiaomi+8%29',
            'Host': 'guide-acs.m.taobao.com',
        }
        return headers

    def get_x_sign_data(self, params):
        sign_params = {
            "deviceId": params.get("deviceId"),
            "appKey": params.get("appKey"),
            "extdata": params.get("extdata"),
            "utdid": params.get("utdid"),
            "x-features": params.get("x-features"),
            "ttid": params.get("ttid"),
            "v": params.get("v"),
            "sid": params.get("sid"),
            "t": params.get("timestamp")[:10],
            "api": params.get("api"),
            "data": params.get("data"),
            "uid": params.get("uid"),
            "lng": params.get("lng"),
            "lat": params.get("lat"),
            "pageName": params.get("pageName"),
            "pageId": params.get("pageId"),
        }
        x_sign_data = self.get_xsign(sign_params)
        return x_sign_data

    @staticmethod
    def prepare_params(features, v, api, page_name, page_id, data, device_info, lat_lng_info, user_cookie) -> Dict:
        timestamp = str(int(time.time() * 1000000))
        sid = user_cookie.get("cookie2", "")
        uid = user_cookie.get("unb", "")
        params = {
            "x-features": features,
            "v": v,
            "api": api,
            "pageName": page_name,
            "pageId": page_id,
            "deviceId": device_info.get("deviceId"),
            "appKey": device_info.get("appKey"),
            "extdata": device_info.get("extdata"),
            "utdid": device_info.get("utdid"),
            "ttid": device_info.get("ttid"),
            "lng": lat_lng_info.get("lng"),
            "lat": lat_lng_info.get("lat"),
            "sid": sid,
            "uid": uid,
            "data": data,
            "timestamp": timestamp,
        }
        return params

    def get_shop_all_items_data(self, seller_id, shop_id, page):
        data = dict_encode({
            'LBS': '{"SG_TMCS_1H_DS":"xxxxxxxxxxx"}',
            '_inNestedEmbed': 'true',
            '_page_home_isweex_': 'true',
            '_page_inside_embed_': 'true',
            '_useless1': '1',
            '_wx_f_': '1',
            '_wx_shop_render_activity': 'true',
            'active_bd': '1',
            'features': '{}',
            'info': 'wifi',
            'isFlagship': '1',
            'isMiniApp': 'false',
            'isWeexShop': 'true',
            'item_id': '627624856025',
            'm': 'shopitemsearch',
            'miniAppCategoryUrl': '',
            'miniAppDetailUrl': '',
            'n': '10',
            'network': 'wifi',
            'new_shopstar': 'true',
            'page': f'{page}',
            'pre_item_id': '627624856025',
            'searchFramework': 'true',
            'search_wap_mall': 'false',
            'sellerId': f'{seller_id}',
            'setting_on': 'imgBanners,userdoc,tbcode,pricerange,localshop,smartTips,firstCat,dropbox,realsale,insertTexts,tabs',
            'shopFetchTimeout': '200',
            'shopFrameRenderTimestamp': '1621927466956',
            'shopId': f'{shop_id}',
            xxxxxxxxx # 参数太长了,省略,抓包即可,不会抓包的参考上一篇介绍。
        })
        return data

    def get_shop_all_items(self, seller_id, shop_id, page):
        features = "27"
        api = "mtop.taobao.wsearch.appsearch"
        v = "1.0"
        page_name = "com.taobao.android.shop.activity.ShopRenderActivity"
        page_id = "http%3A%2F%2Fh5.m.taobao.com%2Fweex%2Fviewpage.htm"
        api_url = f"http://guide-acs.m.taobao.com/gw/{api}/{v}/"
        lat_lng_info = self.random_lat_lng()
        device_info = self.random_device_info()
        user_cookie = {}
        data = self.get_shop_all_items_data(seller_id, shop_id, page)
        params = self.prepare_params(features, v, api, page_name, page_id, data, device_info, lat_lng_info, user_cookie)
        x_sign_data = self.get_x_sign_data(params)
        params["user-agent"] = device_info["user-agent"]
        headers = self.get_header(params, x_sign_data)
        return api_url, data, headers, user_cookie

    def test_shop_all_items(self, seller_id, shop_id, page):
        api_url, data, headers, cookie = self.get_shop_all_items(seller_id, shop_id, page)
        params = {"data": data}
        try:
            response = requests.get(api_url, params=params, headers=headers, cookies=cookie, timeout=3, verify=False)
        except:
            return None
        return response

@timer
def test_shop_items(seller_id, shop_id):
    obj = TBBaseClass()
    totalPage = None
    for page in range(1, 100):
        if totalPage is not None and page > totalPage:
            break
        while True:
            res = obj.test_shop_all_items(seller_id, shop_id, page)
            if res.status_code == 200:
                totalPage = int(res.json()["data"]["totalPage"])
                t_page = int(res.json()["data"]["page"])
                totalResults = int(res.json()["data"]["totalResults"])
                item_ids = [i["item_id"] for i in res.json()["data"]["itemsArray"]]
                print(f"店铺商品总数:{totalResults}, 总页数:{totalPage}, 当前页数:{t_page}, item_ids:{item_ids}",)
                break
            else:
                continue
seller_id = "3948263976"
shop_id = "251740197"
test_shop_items(seller_id, shop_id)

测试结果如下:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值