-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
很难抢到菜,逻辑似乎有问题 #41
Comments
可以提供下对应的 code 吗 |
我只会c语言,不懂go ,只是抢菜几次发现成功率对比手动抢没有优势。然后看log输出每次都有获取购物车的信息,所以就这么猜测了,然后看了一下你的代码,好像印证了我的猜测。我会go的话就改掉测试,然后pr了。所以还需要你检查一下 |
类似下面这种,在几种状态之间切换,当然还要考虑延时的问题。我记得你其中有一个延时使用 3+rand() 秒来延时的,太长了,以设置的ms级别来,关于封号的问题,我把延时设置为1ms 5ms都不见有封号的现象,没有长时间运行,15分钟以内,几个号跑的,都不见有封号
} |
对应的 状态码 哈 |
是的哈,等你的更新,哈哈 |
大概这样?没学过go,编译环境都没有,瞎改的不知道能不能用 func (s *Session) run(ctx context.Context) error {
logrus.Info("=====> 获取购物车中有效商品")
if err := s.CartAllCheck(ctx); err != nil {
return fmt.Errorf("全选购物车商品失败: %v", err)
}
cartData, err := s.GetCart(ctx)
if err != nil {
return err
}
products := cartData["products"].([]map[string]interface{})
for k, v := range products {
logrus.Infof("[%v] %s 数量:%v 总价:%s", k, v["product_name"], v["count"], v["total_price"])
}
for {
for {
logrus.Info("=====> 获取可预约时间")
multiReserveTime, err := s.GetMultiReserveTime(ctx, products)
if err != nil {
logrus.Errorf("获取可预约时间失败: %v", err)
} else {
break
}
if len(multiReserveTime) == 0 {
return ErrorNoReserveTime
} else {
break
}
time.Sleep(time.Duration(s.cfg.DDMC.Interval) * time.Millisecond)
}
logrus.Infof("发现可用的配送时段!")
logrus.Info("=====> 生成订单信息")
for {
checkOrderData, err := s.CheckOrder(ctx, cartData, multiReserveTime)
if err != nil {
logrus.Errorf("检查订单失败: %v", err)
} else {
logrus.Infof("订单总金额:%v\n", checkOrderData["price"])
break
}
time.Sleep(time.Duration(s.cfg.DDMC.Interval) * time.Millisecond)
}
for {
sess := s.Clone()
sess.SetReserve(multiReserveTime[0])
startTime := time.Unix(int64(sess.Reserve.StartTimestamp), 0).Format("2006/01/02 15:04:05")
endTime := time.Unix(int64(sess.Reserve.EndTimestamp), 0).Format("2006/01/02 15:04:05")
timeRange := startTime + "——" + endTime
logrus.Infof("=====> 提交订单中, 预约时间段(%s)", timeRange)
if err := sess.CreateOrder(context.Background(), cartData, checkOrderData); err != nil {
logrus.Errorf("提交订单(%s)失败: %v", timeRange, err)
} else {
break
}
time.Sleep(time.Duration(s.cfg.DDMC.Interval) * time.Millisecond)
}
if err := s.noticeIns.Notice("抢菜成功", "叮咚买菜 抢菜成功,请尽快支付!"); err != nil {
logrus.Warningf("通知失败: %v", err)
}
return nil
}
} |
https://github.com/zc2638/ddshop/blob/main/core/ddmc/session.go#L195-L230 func (s *Session) GetAddress() (map[string]AddressItem, error) {
...
resp, err := s.execute(context.Background(), req, http.MethodGet, urlPath, maxRetryCount)
if err != nil {
return nil, err
}
... 在请求层面直接就重试了哦,可以避免再次构建参数带来的时间和性能损耗 |
今天测试了, |
@chenxuuu 是的,现实中比手动抢菜成功率低,哈哈 |
在6:00和8:30 提交订单页面好像是会自动获取可配送时间的(对应的可能是post请求不需要填写 reserved_time_start ), 所以比较好的逻辑或许是前面的逻辑成功以后 不在进行重试 而是不停的发送addNewOrder请求? (对应的手动不停点击提交订单), 对于使用者而言应该添加更多的菜品(因为会自动剔除缺货的菜品)
在6:00和8:30 提交订单页面好像是会自动获取可配送时间的(对应的可能是post请求不需要填写 reserved_time_start ), 所以比较好的逻辑或许是前面的逻辑成功以后 不在进行重试 而是不停的发送addNewOrder请求? (对应的手动不停点击提交订单), 对于使用者而言应该添加更多的菜品(因为会自动剔除缺货的菜品) |
https://github.com/zc2638/ddshop/blob/main/core/ddmc/session.go#L127-L183 增加了购物车商品 及 可配送时间缓存,可以看看新逻辑 |
关于重试 是不是可以直接用框架 处理好了 是否重试的业务逻辑 可以写在外面 类似 https://pkg.go.dev/github.com/avast/retry-go 😄 |
func (s *Session) execute(ctx context.Context, request *resty.Request, method, url string, count int) (*resty.Response, error) {
...
resp, err := request.Execute(method, url)
if err != nil {
return nil, fmt.Errorf("request failed: %v", err)
}
...
count--
return s.execute(nil, request, method, url, count)
} 在请求层面已经retry了 |
没有可预约时间的情况下,使用3+rand() 秒延时,这个太大了,应该用ms级延时,或者放到配置文件里。有时候没有预约时间,刷新又能有 |
我发现 sku spu 不一样 但是都是同种商品可能性挺大的 |
提交订单失败后就又重新跑一边获取购物车,配送时间 ,应该是 循环获取购物车,成功后循环获取配送时间段,成功后循环提交订单,提交订单失败又分几种,1. 购物车商品全部是无效的->退出 2. 购物车商品部分无效->更新购物车 3. 无配送时间段->循环获取配送时间段 4. 网络繁忙->继续提交订单。 就几种状态,建议用一个状态机,for循环
The text was updated successfully, but these errors were encountered: