前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >监控商品库存方法之二——抓包&逆向

监控商品库存方法之二——抓包&逆向

作者头像
偶尔敲代码
发布2023-04-28 10:28:18
4330
发布2023-04-28 10:28:18
举报
文章被收录于专栏:偶尔敲代码

继上一篇。

Selenium虽然模拟用户操作显得比较真实,但毕竟动用了浏览器,并按手动操作执行,效率上显然是极低的,而且耗用巨大系统资源(Chrome

)。所以总需要更直接高效的方式,那就是抓包再发包了。

01

商品页面

要到达商品页面,就先在浏览器上登陆,通过下方的地址进入登录页面,接码即可。

代码语言:javascript
复制
https://m.laiyifen.com/my/login?loginFrom=%2Fmy%2Findex

然后就来到了商品页面,如下图:

02

抓包分析

浏览器按下F12,切换到“网络”选项卡,F5刷新页面,发现出现一大堆数据包。在下方图片这条发现了该商品的详细信息:

与第一步中的商品页面一毛一样,其中的stockStatus就是我们想要的库存状态,获取该值就可以判断有没有库存。

再看这个数据包的具体链接:

代码语言:javascript
复制
https://openapi.laiyifen.com/community-app-api/v1/community/product/secret?times=1677133674158&platform=2&companyId=30&platformId=3&deviceId=d02e61f8-4563-4def-a4c2-e26256314e56&channelSkuUnitId=115812******

看起来就是调用了官方的api去获取信息,用工具测试一下,哇嘎,非法。

带上协议头测试一下,哇靠,时间戳验证失败

后面把网址和协议头的时间戳都替换了,发现还是验证失败或非法

多次发包后,发现协议头的x-co-sign会变化,所以重点就转移到分析这个参数的来源了。

03

逆向

虽然不情愿也不懂,那都到这一步了,也得去试试看,万一被我找出来x-co-sign怎么来的呢

果断搜索x-co-sign,定位到js文件里具体位置,如下图:

切换到“来源”选项卡,在该行位置下断点:

刷新页面,得到下面的结果:

可以看出来核心代码在4062-4069行,反推回去,就是: 变量f的值赋给x-co-sign;

变量f是由变量h转换的字符串;

变量h是对变量d进行HmacSHA1加密,秘钥等下找;

变量d就在4062行了。

我们将变量d输出:

代码语言:javascript
复制
GET\n/community-app-api/v1/community/product/secret\nchannelSkuUnitId=115812121*****&companyId=30&deviceId=d02e61f8-4563-4def-a4c2-e26256314e56&platform=2&platformId=3&times=1677135596412\nx-co-client:70923143D9C04D1390617B676BF4ACA7\nx-co-timestamp:1677135596663

分析发现它就是把x-co-client,x-co-timestamp,SkuUnitId等参数组成,都很简单了,时间戳就按发包的时间,SkuUnitId就是商品id了,所以构造这个变量d很简单了。

变量d有了就差秘钥了,直接打印看看,看起来是明文。

为了验证,搜索secretKey,发现就是个常量,那就真是明文了,搞定了。

04

效果及代码

最终效果就是这样了:

实际应用时,x-co-client、deviceId和clientInfo 等这些跟设备有关的信息需要相应更改,代码供参考。

代码语言:javascript
复制
import requests,json,time
from urllib import parse
from hashlib import sha1
import base64
import hmac

p_token= '' #push+
skuid = ["11581212********","11581212*********","1158121********"]#DD,YH,HM

def hash_hmac(key, code, sha1):
    hmac_code = hmac.new(key.encode(), code.encode(), sha1).digest()
    return base64.b64encode(hmac_code).decode()
n = 1 #循环次数
DDok = 0 #有货次数
HMok = 0 #有货次数
YHok = 0 #有货次数
a = input('输入 延时时间(s) 回车后继续:')
if a == "":
    延时时间 = 3  # 延时时间
    print("未设置,按默认延时时间(s):"+str(延时时间))
else:
    延时时间 = int(a)  # 延时时间
    print("延时时间(s):" + str(延时时间))
print('输入欲监控的商品[DD,YH,HM]对应位置为1,不监控为0,以.隔开。如1.0.1 表示监控DD,HM')
a = input('输入数字回车后继续:')
if a == "":
    执行 = [1, 1, 1]
    print("未设置,按默认监控所有")
else:
    # 将输入每个数以.隔开做成数组
    执行 = [int(k) for k in a.split(".")]

while True:
    t = int(time.time()*1000)#13时间戳
    t = str(t)
    #print(t)
    i = 0
    for i in range(3):
        #x-co-sign明文
        k = f'GET\n/community-app-api/v1/community/product/secret\nchannelSkuUnitId={skuid[i]}&companyId=30&deviceId=9f05fde7-7a72-4614-b6cc-bb1ad6f39edd&platform=2&platformId=3&times={t}\nx-co-client:70923143D9C04D1390617B676BF4ACA7\nx-co-timestamp:{t}'
        #print(k)
        x_co_sign = hash_hmac('SECRETKEY-9385D4D1F8864252AD2D19', k, sha1)#HMACSHA1加密
        #print(x_co_sign)
        url = f"https://openapi.laiyifen.com/community-app-api/v1/community/product/secret?times={t}&platform=2&companyId=30&platformId=3&deviceId=9f05fde7-7a72-4614-b6cc-bb1ad6f39edd&channelSkuUnitId={skuid[i]}"
        headers = {
            "Host": "openapi.laiyifen.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "X-Requested-With": "XMLHttpRequest",
            "x-co-client": "70923143D9C04D1390617B676BF4ACA7",
            "User-Agent": '''Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36''',
            "clientInfo": "%7B%22platformId%22:2,%22clientSystem%22:%22H5%22%7D",
            "Accept": "application/json",
            "x-co-sign": x_co_sign,
            "x-co-timestamp": t,
            "ut": "4bc91c70bcc9f84bceb2e95f7970bcc451",
            "Origin": "http://m.laiyifen.com",
            "Sec-Fetch-Site": "cross-site",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Dest": "empty",
            "Referer": "https://m.laiyifen.com/",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9"}
        try:  
            if 执行[i] == 1:
                response = requests.get(url=url, headers=headers)
            #print(response.text)
                if response.text.find("stockStatus") != -1:
                    aaa = json.loads(response.text)
                    #print(aaa['data']['productName'],aaa['data']['promotionPrice'],aaa['data']['stockStatus'])
                    if aaa['data']['stockStatus'] != "0":
                        #print(aaa['data']['productName']+"————有货")
                        if i == 0:
                            DDok = DDok + 1
                            print("DD 有货")
                            if DDok <= 3:
                                t = str(time.time())
                                content = parse.quote_plus(t) 
                                title = parse.quote_plus('DD 有货') 
                                requests.get(f'http://www.pushplus.plus/send?token={p_token}&title={title}&content={content}')
                        elif i == 1:
                            YHok = YHok + 1
                            print("YH 有货")
                            if YHok <= 3:
                                t = str(time.time())
                                content = parse.quote_plus(t) 
                                title = parse.quote_plus('YH 有货') 
                                requests.get(f'http://www.pushplus.plus/send?token={p_token}&title={title}&content={content}')
                        else:
                            HMok = HMok + 1
                            print("HM 有货")
                            if HMok <= 3:
                                t = str(time.time())
                                content = parse.quote_plus(t) 
                                title = parse.quote_plus('HM 有货') 
                                requests.get(f'http://www.pushplus.plus/send?token={p_token}&title={title}&content={content}')
                    else:
                        #print(aaa['data']['productName'])
                        if i == 0:
                            print("DD 已售罄")
                        elif i == 1:
                            print("YH 已售罄")
                        else:
                            print("HM 已售罄")
                else:
                    print(response.text,11111)
        except Exception:  
            print('异常,未获取到数据')
        i = i + 1
        time.sleep(0.3)#每次运行3个商品间隔0.3秒
    print(f"已运行{n}次")
    if DDok+HMok+YHok >= 6:  # 总共提醒了6次就结束循环
        print("已监控到6次,结束运行")
        break
    n = n + 1
    time.sleep(延时时间)

input('输入回车后继续:')



以上代码及思路仅供学习参考,请勿用于非法用途。

如果喜欢,欢迎打赏支持,让我更有动力。 - End -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 偶尔敲代码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档