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

继上一篇。

Selenium虽然模拟用户操作显得比较真实,但毕竟动用了浏览器,并按手动操作执行,效率上显然是极低的,而且耗用巨大系统资源(Chrome4348c1547c02d6c271b1a6786b1f07c9.png)。所以总需要更直接高效的方式,那就是抓包再发包了。

01

商品页面

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

https://m.laiyifen.com/my/login?loginFrom=%2Fmy%2Findex

d3085566a61e19f144f340d5df1e389d.png

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

2085c3cde05d0685032881822228cc86.png

02


抓包分析

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

f1d8e56e526bc7c6af0bf1cbe19821a5.png

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

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

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去获取信息,用工具测试一下,哇嘎,非法d826d0c489fd6dda099d246acbdb2012.png

6dbf93fd00366ebdc660e537bdf2752f.png

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

fa7aadbdaef819479526742ddc579e68.png

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

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

03


逆向

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

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

61d53620491634e2917775b4300a3cd6.png

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

3cc1a1a18802fa5bd3badc153c08e8aa.png

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

d95332bef0a79f844851d9bc7ec0cceb.png

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

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

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

变量d就在4062行了。

我们将变量d输出:

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有了就差秘钥了,直接打印看看,看起来是明文。

42c897b424c3fd371679f836fdcc64ae.png

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

f3562c2eea41025b6d4763ad21e06dc9.png

04


效果及代码

最终效果就是这样了:

a5ebe5cc6d59cc231a103f1d49ca0ab9.png

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

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('输入回车后继续:')

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

a2bb05ea519edb41c2f3819d6fe9746a.png

如果喜欢,欢迎打赏支持,让我更有动力format,png

- End -

更多精彩文章

点击下方名片关注【偶尔敲代码】

点亮小花60415dd0138e7cd5d736cafa4c9b7514.gif 让更多人了解

eecb9698ffc7fba29414ceee8a4ac604.gif

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于商城商品库存监测工具使用方法的几点说明   这个只有几十KB的小程序是自己业余时间写的,功能比较简单,只是定时&ldquo;扫描&rdquo;自己关注的商品库存情况,当达到&ldquo;兑换&rdquo;条件时进行提醒。在这里把使用时的几点事项说明一下:   1. 压缩里一共有6个文件,分别是:     百度知道商城商品监测.exe&mdash;&mdash;主程序     Config.txt&mdash;&mdash;配置文件     Folder.wav&mdash;&mdash;声音文件     GREEN.ico&mdash;&mdash;图标文件     RED.ico&mdash;&mdash;图标文件   这5个文件是缺一不可的,其中的Folder.wav文件可以用任意PCM格式的wav文件替换,替换时需保持文件名一致。另外还有一个说明文档Readme.txt。   2. 在使用前,需要在电脑上安装.NET Framework4.0,否则程序无法正常使用。微软官网免费下载地址:http://www.microsoft.com/zh-cn/download/details.aspx?id=17718   3. 装好.NET Framework4.0后,打开Config.txt文档进行参数的修改。     第1个参数是监测时间间隔参数:TimerInterval,这个参数指定了&ldquo;多长时间扫描一次&rdquo;,单位是&ldquo;秒&rdquo;,请在&ldquo;=&rdquo;后面用半角阿拉伯数字填写;     第2个参数是商品编码:GoodsIDList,这里可以将所有需要&ldquo;关注&rdquo;的商品编码依次填写到&ldquo;=&rdquo;后面,编码间用英文逗号&quot;,&quot;隔开,如果您不知道某种商品的编码是多少,可以从知道商城打开这个商品的页面,看看地址栏中的网址,末尾id=后面的数字就是商品编码。     第3个参数是用户名:UserName,请把您的知道用户名填写到&ldquo;=&rdquo;后面,以便监测您的财富值变化情况;     第4个参数是声音提示开关:Sound,此处只接受2个值,要么关闭声音&ldquo;Off&rdquo;,要么打开声音&ldquo;On&rdquo;,填写其它字符是不能关闭提示音的。   4. 运行程序,程序会在右下角系统托盘中显示一个绿色图标,当指定的某种商品符合&ldquo;兑换&rdquo;条件时,右下角图标会变为红色,并弹出气球提示,双击红色图标即可激活窗体查看,窗体中用绿色底色标注的商品即为可&ldquo;兑换&rdquo;商品,并可通过双击相应行打开商品页面进行&ldquo;抢购&rdquo;。如果窗体中有红色底色标注的商品,说明此商品&ldquo;有货&rdquo;但您的财富值不够,无法兑换。每次扫描库存后凡无法&ldquo;兑换&rdquo;的商品信息会在下次扫描时清空,有库存且有足够财富值兑换的商品信息将保留(每扫描一次 提示一次 增加一行,直至库存减为0)。   5. 点击窗体右上角关闭按钮即可隐藏程序主窗体,只保留右下方系统托盘图标,双击图标即可重新显示窗体,若想完全退出程序,请在右下角托盘图标上点右键,选择&ldquo;退出程序&rdquo;。    ★★朋友们反映的问题★★   ◆关于&ldquo;一直出现提示&rdquo;的问题:   这个问题预计在下个版本中解决,目前程序中未做设置,只要商品能够&ldquo;兑换&rdquo;,哪怕已经&ldquo;兑换&rdquo;过一次,也会弹气球提示,提示音可以在Config.txt中修改Sound=Off关闭,但气球提示无法关闭。   ◆关于窗体中商品&ldquo;经验值&rdquo;的问题:   这里是我在做窗体界面时写错了,应该写为&ldquo;财富值&rdquo;,这个问题之前有几位朋友向我提到过,一直也没改,下个版本一并解决吧!   这是我能想到的一些地方,若朋友们还有其它问题,可以与我邮件联系:805867711@qq.com   希望大家玩得开心!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值