From 612b5e54716736aab6756c7190a1b857210b8962 Mon Sep 17 00:00:00 2001 From: dandyhuang Date: Mon, 4 Jan 2021 17:53:43 +0800 Subject: [PATCH 1/9] fix: jsonp --- jd_seckill/seckill.go | 317 +++++++++++++++++++++--------------------- 1 file changed, 159 insertions(+), 158 deletions(-) diff --git a/jd_seckill/seckill.go b/jd_seckill/seckill.go index dd27a65..7967c01 100644 --- a/jd_seckill/seckill.go +++ b/jd_seckill/seckill.go @@ -18,217 +18,218 @@ import ( type Seckill struct { client *httpc.HttpClient - conf *goconfig.ConfigFile + conf *goconfig.ConfigFile } -func NewSeckill(client *httpc.HttpClient,conf *goconfig.ConfigFile) *Seckill { - return &Seckill{client: client,conf: conf} +func NewSeckill(client *httpc.HttpClient, conf *goconfig.ConfigFile) *Seckill { + return &Seckill{client: client, conf: conf} } func (this *Seckill) getUserAgent() string { - return this.conf.MustValue("config","default_user_agent","") + return this.conf.MustValue("config", "default_user_agent", "") } -func (this *Seckill) SkuTitle() (string,error) { - skuId:=this.conf.MustValue("config","sku_id","") - req:=httpc.NewRequest(this.client) - resp,body,err:=req.SetUrl(fmt.Sprintf("https://item.jd.com/%s.html",skuId)).SetMethod("get").Send().End() - if err!=nil || resp.StatusCode!=http.StatusOK { +func (this *Seckill) SkuTitle() (string, error) { + skuId := this.conf.MustValue("config", "sku_id", "") + req := httpc.NewRequest(this.client) + resp, body, err := req.SetUrl(fmt.Sprintf("https://item.jd.com/%s.html", skuId)).SetMethod("get").Send().End() + if err != nil || resp.StatusCode != http.StatusOK { log.Println("访问商品详情失败") - return "",errors.New("访问商品详情失败") + return "", errors.New("访问商品详情失败") } - html:=strings.NewReader(body) - doc,_:=goquery.NewDocumentFromReader(html) - return strings.TrimSpace(doc.Find(".sku-name").Text()),nil + html := strings.NewReader(body) + doc, _ := goquery.NewDocumentFromReader(html) + return strings.TrimSpace(doc.Find(".sku-name").Text()), nil } func (this *Seckill) MakeReserve() { - user:=NewUser(this.client,this.conf) - userInfo,_:=user.GetUserInfo() - log.Println("用户:"+userInfo) - shopTitle,err:=this.SkuTitle() - if err!=nil { + user := NewUser(this.client, this.conf) + userInfo, _ := user.GetUserInfo() + log.Println("用户:" + userInfo) + shopTitle, err := this.SkuTitle() + if err != nil { log.Println("获取商品信息失败") - }else{ - log.Println("商品名称:"+shopTitle) + } else { + log.Println("商品名称:" + shopTitle) } - skuId:=this.conf.MustValue("config","sku_id","") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) - resp,body,err:=req.SetUrl("https://yushou.jd.com/youshouinfo.action?callback=fetchJSON&sku="+skuId+"&_="+strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() - if err!=nil || resp.StatusCode!=http.StatusOK { + skuId := this.conf.MustValue("config", "sku_id", "") + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) + resp, body, err := req.SetUrl("https://yushou.jd.com/youshouinfo.action?callback=fetchJSON&sku=" + skuId + "&_=" + strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() + if err != nil || resp.StatusCode != http.StatusOK { log.Println("预约商品失败") - }else{ - reserveUrl:=gjson.Get(body,"url").String() - req=httpc.NewRequest(this.client) - _,_,_=req.SetUrl("https:"+reserveUrl).SetMethod("get").Send().End() + } else { + reserveUrl := gjson.Get(body, "url").String() + req = httpc.NewRequest(this.client) + _, _, _ = req.SetUrl("https:" + reserveUrl).SetMethod("get").Send().End() log.Println("预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约") } } -func (this *Seckill) getSeckillUrl() (string,error) { - skuId:=this.conf.MustValue("config","sku_id","") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Host","itemko.jd.com") - req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) - url:="" - for { - _,body,_:=req.SetUrl("https://itemko.jd.com/itemShowBtn?callback=jQuery{}"+strconv.Itoa(common.Rand(1000000,9999999))+"&skuId="+skuId+"&from=pc&_="+strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() - if gjson.Get(body,"url").Exists() && gjson.Get(body,"url").String()!="" { - url=gjson.Get(body,"url").String() +func (this *Seckill) getSeckillUrl() (string, error) { + skuId := this.conf.MustValue("config", "sku_id", "") + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Host", "itemko.jd.com") + req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) + url := "" + for { + _, body, _ := req.SetUrl("https://itemko.jd.com/itemShowBtn?callback=jQuery{}" + strconv.Itoa(common.Rand(1000000, 9999999)) + "&skuId=" + skuId + "&from=pc&_=" + strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() + urlbody := strings.Trim(strings.Split(body, "(")[1], ")") + if gjson.Get(urlbody, "url").Exists() && gjson.Get(urlbody, "url").String() != "" { + url = gjson.Get(urlbody, "url").String() break } log.Println("抢购链接获取失败,稍后自动重试") - time.Sleep(300*time.Millisecond) + time.Sleep(300 * time.Millisecond) } //https://divide.jd.com/user_routing?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc - url=strings.ReplaceAll(url,"divide","marathon") + url = strings.ReplaceAll(url, "divide", "marathon") //https://marathon.jd.com/captcha.html?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc - url=strings.ReplaceAll(url,"user_routing","captcha.html") - log.Println("抢购链接获取成功:"+url) - return url,nil + url = strings.ReplaceAll(url, "user_routing", "captcha.html") + log.Println("抢购链接获取成功:" + url) + return url, nil } -func (this *Seckill) RequestSeckillUrl() { - user:=NewUser(this.client,this.conf) - userInfo,_:=user.GetUserInfo() - log.Println("用户:"+userInfo) - shopTitle,err:=this.SkuTitle() - if err!=nil { +func (this *Seckill) RequestSeckillUrl() { + user := NewUser(this.client, this.conf) + userInfo, _ := user.GetUserInfo() + log.Println("用户:" + userInfo) + shopTitle, err := this.SkuTitle() + if err != nil { log.Println("获取商品信息失败") - }else{ - log.Println("商品名称:"+shopTitle) + } else { + log.Println("商品名称:" + shopTitle) } - url,_:=this.getSeckillUrl() - skuId:=this.conf.MustValue("config","sku_id","") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Host","marathon.jd.com") - req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) - _,_,_=req.SetUrl(url).SetMethod("get").Send().End() + url, _ := this.getSeckillUrl() + skuId := this.conf.MustValue("config", "sku_id", "") + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Host", "marathon.jd.com") + req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) + _, _, _ = req.SetUrl(url).SetMethod("get").Send().End() } -func (this *Seckill) SeckillPage() { +func (this *Seckill) SeckillPage() { log.Println("访问抢购订单结算页面...") - skuId:=this.conf.MustValue("config","sku_id","") - seckillNum:=this.conf.MustValue("config","seckill_num","") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Host","marathon.jd.com") - req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) - _,_,_=req.SetUrl("https://marathon.jd.com/seckill/seckill.action?skuId="+skuId+"&num="+seckillNum+"&rid="+strconv.Itoa(int(time.Now().Unix()))).SetMethod("get").Send().End() + skuId := this.conf.MustValue("config", "sku_id", "") + seckillNum := this.conf.MustValue("config", "seckill_num", "") + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Host", "marathon.jd.com") + req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) + _, _, _ = req.SetUrl("https://marathon.jd.com/seckill/seckill.action?skuId=" + skuId + "&num=" + seckillNum + "&rid=" + strconv.Itoa(int(time.Now().Unix()))).SetMethod("get").Send().End() } -func (this *Seckill) SeckillInitInfo() (string,error) { +func (this *Seckill) SeckillInitInfo() (string, error) { log.Println("获取秒杀初始化信息...") - skuId:=this.conf.MustValue("config","sku_id","") - seckillNum:=this.conf.MustValue("config","seckill_num","") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Host","marathon.jd.com") - req.SetData("sku",skuId) - req.SetData("num",seckillNum) - req.SetData("isModifyAddress","false") - resp,body,err:=req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/init.action").SetMethod("post").Send().End() - if err!=nil || resp.StatusCode!=http.StatusOK { + skuId := this.conf.MustValue("config", "sku_id", "") + seckillNum := this.conf.MustValue("config", "seckill_num", "") + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Host", "marathon.jd.com") + req.SetData("sku", skuId) + req.SetData("num", seckillNum) + req.SetData("isModifyAddress", "false") + resp, body, err := req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/init.action").SetMethod("post").Send().End() + if err != nil || resp.StatusCode != http.StatusOK { log.Println("初始化秒杀信息失败") - return "",errors.New("初始化秒杀信息失败") + return "", errors.New("初始化秒杀信息失败") } if !gjson.Valid(body) { - log.Println("抢购失败,返回信息:"+body) - return "", errors.New("抢购失败,返回信息:"+body) + log.Println("抢购失败,返回信息:" + body) + return "", errors.New("抢购失败,返回信息:" + body) } - return body,nil + return body, nil } func (this *Seckill) SubmitSeckillOrder() bool { - eid:=this.conf.MustValue("config","eid","") - fp:=this.conf.MustValue("config","fp","") - skuId:=this.conf.MustValue("config","sku_id","") - seckillNum:=this.conf.MustValue("config","seckill_num","") - paymentPwd:=this.conf.MustValue("account","payment_pwd","") - initInfo,err:=this.SeckillInitInfo() - if err!=nil { - log.Println(fmt.Sprintf("抢购失败,无法获取生成订单的基本信息,接口返回:【%s】",err.Error())) + eid := this.conf.MustValue("config", "eid", "") + fp := this.conf.MustValue("config", "fp", "") + skuId := this.conf.MustValue("config", "sku_id", "") + seckillNum := this.conf.MustValue("config", "seckill_num", "") + paymentPwd := this.conf.MustValue("account", "payment_pwd", "") + initInfo, err := this.SeckillInitInfo() + if err != nil { + log.Println(fmt.Sprintf("抢购失败,无法获取生成订单的基本信息,接口返回:【%s】", err.Error())) return false } - address:=gjson.Get(initInfo,"addressList").Array() - defaultAddress:=address[0] - isinvoiceInfo:=gjson.Get(initInfo,"invoiceInfo").Exists() - invoiceTitle:="-1" - invoiceContentType:="-1" - invoicePhone:="" - invoicePhoneKey:="" - invoiceInfo:="false" + address := gjson.Get(initInfo, "addressList").Array() + defaultAddress := address[0] + isinvoiceInfo := gjson.Get(initInfo, "invoiceInfo").Exists() + invoiceTitle := "-1" + invoiceContentType := "-1" + invoicePhone := "" + invoicePhoneKey := "" + invoiceInfo := "false" if isinvoiceInfo { - invoiceTitle=gjson.Get(initInfo,"invoiceInfo.invoiceTitle").String() - invoiceContentType=gjson.Get(initInfo,"invoiceInfo.invoiceContentType").String() - invoicePhone=gjson.Get(initInfo,"invoiceInfo.invoicePhone").String() - invoicePhoneKey=gjson.Get(initInfo,"invoiceInfo.invoicePhoneKey").String() - invoiceInfo="true" + invoiceTitle = gjson.Get(initInfo, "invoiceInfo.invoiceTitle").String() + invoiceContentType = gjson.Get(initInfo, "invoiceInfo.invoiceContentType").String() + invoicePhone = gjson.Get(initInfo, "invoiceInfo.invoicePhone").String() + invoicePhoneKey = gjson.Get(initInfo, "invoiceInfo.invoicePhoneKey").String() + invoiceInfo = "true" } - token:=gjson.Get(initInfo,"token").String() + token := gjson.Get(initInfo, "token").String() log.Println("提交抢购订单...") - req:=httpc.NewRequest(this.client) - req.SetHeader("User-Agent",this.getUserAgent()) - req.SetHeader("Host","marathon.jd.com") - req.SetHeader("Referer",fmt.Sprintf("https://marathon.jd.com/seckill/seckill.action?skuId=%s&num=%s&rid=%d",skuId,seckillNum,int(time.Now().Unix()))) - req.SetData("skuId",skuId) - req.SetData("num",seckillNum) - req.SetData("addressId",defaultAddress.Get("id").String()) - req.SetData("yuShou","true") - req.SetData("isModifyAddress","false") - req.SetData("name",defaultAddress.Get("name").String()) - req.SetData("provinceId",defaultAddress.Get("provinceId").String()) - req.SetData("cityId",defaultAddress.Get("cityId").String()) - req.SetData("countyId",defaultAddress.Get("countyId").String()) - req.SetData("townId",defaultAddress.Get("townId").String()) - req.SetData("addressDetail",defaultAddress.Get("addressDetail").String()) - req.SetData("mobile",defaultAddress.Get("mobile").String()) - req.SetData("mobileKey",defaultAddress.Get("mobileKey").String()) - req.SetData("email",defaultAddress.Get("email").String()) - req.SetData("postCode","") - req.SetData("invoiceTitle",invoiceTitle) - req.SetData("invoiceCompanyName","") - req.SetData("invoiceContent",invoiceContentType) - req.SetData("invoiceTaxpayerNO","") - req.SetData("invoiceEmail","") - req.SetData("invoicePhone",invoicePhone) - req.SetData("invoicePhoneKey",invoicePhoneKey) - req.SetData("invoice",invoiceInfo) - req.SetData("password",paymentPwd) - req.SetData("codTimeType","3") - req.SetData("paymentType","4") - req.SetData("areaCode","") - req.SetData("overseas","0") - req.SetData("phone","") - req.SetData("eid",eid) - req.SetData("fp",fp) - req.SetData("token",token) - req.SetData("pru","") - resp,body,err:=req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action?skuId="+skuId).SetMethod("post").Send().End() - if err!=nil || resp.StatusCode!=http.StatusOK { + req := httpc.NewRequest(this.client) + req.SetHeader("User-Agent", this.getUserAgent()) + req.SetHeader("Host", "marathon.jd.com") + req.SetHeader("Referer", fmt.Sprintf("https://marathon.jd.com/seckill/seckill.action?skuId=%s&num=%s&rid=%d", skuId, seckillNum, int(time.Now().Unix()))) + req.SetData("skuId", skuId) + req.SetData("num", seckillNum) + req.SetData("addressId", defaultAddress.Get("id").String()) + req.SetData("yuShou", "true") + req.SetData("isModifyAddress", "false") + req.SetData("name", defaultAddress.Get("name").String()) + req.SetData("provinceId", defaultAddress.Get("provinceId").String()) + req.SetData("cityId", defaultAddress.Get("cityId").String()) + req.SetData("countyId", defaultAddress.Get("countyId").String()) + req.SetData("townId", defaultAddress.Get("townId").String()) + req.SetData("addressDetail", defaultAddress.Get("addressDetail").String()) + req.SetData("mobile", defaultAddress.Get("mobile").String()) + req.SetData("mobileKey", defaultAddress.Get("mobileKey").String()) + req.SetData("email", defaultAddress.Get("email").String()) + req.SetData("postCode", "") + req.SetData("invoiceTitle", invoiceTitle) + req.SetData("invoiceCompanyName", "") + req.SetData("invoiceContent", invoiceContentType) + req.SetData("invoiceTaxpayerNO", "") + req.SetData("invoiceEmail", "") + req.SetData("invoicePhone", invoicePhone) + req.SetData("invoicePhoneKey", invoicePhoneKey) + req.SetData("invoice", invoiceInfo) + req.SetData("password", paymentPwd) + req.SetData("codTimeType", "3") + req.SetData("paymentType", "4") + req.SetData("areaCode", "") + req.SetData("overseas", "0") + req.SetData("phone", "") + req.SetData("eid", eid) + req.SetData("fp", fp) + req.SetData("token", token) + req.SetData("pru", "") + resp, body, err := req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action?skuId=" + skuId).SetMethod("post").Send().End() + if err != nil || resp.StatusCode != http.StatusOK { log.Println("抢购失败,网络错误") - _=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,网络错误") + _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,网络错误") return false } if !gjson.Valid(body) { - log.Println("抢购失败,返回信息:"+body) - _=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,返回信息:"+body) + log.Println("抢购失败,返回信息:" + body) + _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,返回信息:"+body) return false } - if gjson.Get(body,"success").Bool() { - orderId:=gjson.Get(body,"orderId").String() - totalMoney:=gjson.Get(body,"totalMoney").String() - payUrl:="https:"+gjson.Get(body,"pcUrl").String() - log.Println(fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s",orderId,totalMoney,payUrl)) - _=service.SendMessage(this.conf,"茅台抢购通知",fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s",orderId,totalMoney,payUrl)) + if gjson.Get(body, "success").Bool() { + orderId := gjson.Get(body, "orderId").String() + totalMoney := gjson.Get(body, "totalMoney").String() + payUrl := "https:" + gjson.Get(body, "pcUrl").String() + log.Println(fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s", orderId, totalMoney, payUrl)) + _ = service.SendMessage(this.conf, "茅台抢购通知", fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s", orderId, totalMoney, payUrl)) return true - }else{ - log.Println("抢购失败,返回信息:"+body) - _=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,返回信息:"+body) + } else { + log.Println("抢购失败,返回信息:" + body) + _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,返回信息:"+body) return false } -} \ No newline at end of file +} From c7c96aaa73402d3f63f7bec2369929cf5f25d6e3 Mon Sep 17 00:00:00 2001 From: dandyhuang Date: Mon, 4 Jan 2021 19:04:41 +0800 Subject: [PATCH 2/9] fix: jsonp --- jd_seckill/seckill.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jd_seckill/seckill.go b/jd_seckill/seckill.go index 7967c01..32f62dd 100644 --- a/jd_seckill/seckill.go +++ b/jd_seckill/seckill.go @@ -76,9 +76,15 @@ func (this *Seckill) getSeckillUrl() (string, error) { url := "" for { _, body, _ := req.SetUrl("https://itemko.jd.com/itemShowBtn?callback=jQuery{}" + strconv.Itoa(common.Rand(1000000, 9999999)) + "&skuId=" + skuId + "&from=pc&_=" + strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() - urlbody := strings.Trim(strings.Split(body, "(")[1], ")") - if gjson.Get(urlbody, "url").Exists() && gjson.Get(urlbody, "url").String() != "" { - url = gjson.Get(urlbody, "url").String() + var cbBody string + cbBody = body + spBody := strings.Split(body, "(") + if len(spBody) >= 2 { + cbBody = strings.Trim(spBody[1], ")") + } + + if gjson.Get(cbBody, "url").Exists() && gjson.Get(cbBody, "url").String() != "" { + url = gjson.Get(cbBody, "url").String() break } log.Println("抢购链接获取失败,稍后自动重试") From 9bf6c38f35f8f73f31bc5addc43b7bc285a09b96 Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 19:37:02 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E7=BB=86=E8=8A=82?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/jdTdudfp.go | 4 ++-- cmd/version.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/jdTdudfp.go b/cmd/jdTdudfp.go index 4bf037e..eb1c676 100644 --- a/cmd/jdTdudfp.go +++ b/cmd/jdTdudfp.go @@ -94,7 +94,7 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { chromedp.WaitVisible(".common-submit-btn"), chromedp.Click(".common-submit-btn"), chromedp.WaitVisible("#sumPayPriceId"), - chromedp.Sleep(2*time.Second), + chromedp.Sleep(3*time.Second), chromedp.Evaluate("_JdTdudfp", &res), ) if err != nil { @@ -102,7 +102,7 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { } value:=string(res) if !gjson.Valid(value) { - log.Println("获取失败,请重新尝试") + log.Println("获取失败,请重新尝试,返回信息:"+value) }else{ log.Println("获取成功,请手动填入配置文件") log.Println("eid:"+gjson.Get(value,"eid").String()) diff --git a/cmd/version.go b/cmd/version.go index 53a6185..05f3cf4 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -15,6 +15,6 @@ var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number of jd_seckill", Run: func(cmd *cobra.Command, args []string) { - fmt.Println(fmt.Sprintf("%s version %s%s %s/%s",common.SoftName,common.SoftName,common.Version,runtime.GOOS,runtime.GOARCH)) + fmt.Println(fmt.Sprintf("%s version %s %s %s/%s",common.SoftName,common.SoftName,common.Version,runtime.GOOS,runtime.GOARCH)) }, } \ No newline at end of file From 48dac396b3909b132c802f82e406447ee824fe69 Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 19:38:51 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E5=BC=95=E8=B5=B7=E6=8A=A2=E8=B4=AD=E9=93=BE=E6=8E=A5=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jd_seckill/seckill.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jd_seckill/seckill.go b/jd_seckill/seckill.go index 32f62dd..e493eff 100644 --- a/jd_seckill/seckill.go +++ b/jd_seckill/seckill.go @@ -73,9 +73,12 @@ func (this *Seckill) getSeckillUrl() (string, error) { req.SetHeader("User-Agent", this.getUserAgent()) req.SetHeader("Host", "itemko.jd.com") req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) + req.SetUrl("https://itemko.jd.com/itemShowBtn?callback=jQuery" + strconv.Itoa(common.Rand(1000000, 9999999)) + "&skuId=" + skuId + "&from=pc&_=" + strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get") url := "" for { - _, body, _ := req.SetUrl("https://itemko.jd.com/itemShowBtn?callback=jQuery{}" + strconv.Itoa(common.Rand(1000000, 9999999)) + "&skuId=" + skuId + "&from=pc&_=" + strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() + _, body, _ := req.Send().End() + //临时打印数据 + log.Println("返回信息:"+body) var cbBody string cbBody = body spBody := strings.Split(body, "(") @@ -90,6 +93,7 @@ func (this *Seckill) getSeckillUrl() (string, error) { log.Println("抢购链接获取失败,稍后自动重试") time.Sleep(300 * time.Millisecond) } + url = "https:"+url //https://divide.jd.com/user_routing?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc url = strings.ReplaceAll(url, "divide", "marathon") //https://marathon.jd.com/captcha.html?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc @@ -110,6 +114,7 @@ func (this *Seckill) RequestSeckillUrl() { } url, _ := this.getSeckillUrl() skuId := this.conf.MustValue("config", "sku_id", "") + log.Println("访问商品的抢购连接...") req := httpc.NewRequest(this.client) req.SetHeader("User-Agent", this.getUserAgent()) req.SetHeader("Host", "marathon.jd.com") From b3a9dd28443367f8c71aa86dd2d9f8b19119a117 Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 20:15:57 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6cc6187..7d15fb5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,16 @@ Jd_Seckill ## 安装 +方式一(推荐): + +```shell +git clone https://github.com/ztino/jd_seckill.git +cd jd_seckill +go get +``` + +方式二: + ```shell go get github.com/ztino/jd_seckill ``` @@ -32,7 +42,7 @@ go get github.com/ztino/jd_seckill jd_seckill login ``` -### 自动获取eif,fp +### 自动获取eid,fp > ⚠依赖谷歌浏览器,请安装谷歌浏览器,获取到的eid和fp请手动填入配置文件 @@ -40,7 +50,7 @@ jd_seckill login ```shell jd_seckill jdTdudfp ``` -> ⚠目前测试阶段,请勿依赖该功能 +> ⚠目前实验性阶段,请勿依赖该功能 ### 预约 执行以下命令按照提示操作: From f0fbc073f862c41c40bcbd3160552e2e2dca74e7 Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 20:54:35 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=BC=80=E6=94=BE=E6=8A=A2=E8=B4=AD?= =?UTF-8?q?=E6=80=BB=E6=97=B6=E9=97=B4,=E6=8A=A2=E8=B4=AD=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=95=B0,=E9=97=B4=E9=9A=94=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=8F=AF=E9=80=9A=E8=BF=87=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/seckill.go | 19 ++++++++++++++----- conf.ini | 10 ++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cmd/seckill.go b/cmd/seckill.go index f6d68c6..8464061 100644 --- a/cmd/seckill.go +++ b/cmd/seckill.go @@ -11,6 +11,7 @@ import ( "log" "net/http" "os" + "strconv" "time" ) @@ -54,7 +55,10 @@ func startSeckill(cmd *cobra.Command, args []string) { seckill:=jd_seckill.NewSeckill(common.Client,common.Config) //开启抢购任务,第二个参数为开启几个协程 //怕封号的可以减少协程数量,相反抢到的成功率也减低了 - Start(seckill,5) + //抢购任务数读取配置文件 + str:=common.Config.MustValue("config","task_num","5") + taskNum,_:=strconv.Atoi(str) + Start(seckill,taskNum) } } @@ -69,17 +73,22 @@ func GetJdTime() (int64,error) { } func Start(seckill *jd_seckill.Seckill,taskNum int) { - seckillTotalTime:=time.Now().Add(2*time.Minute).Unix() + //抢购总时间读取配置文件 + str:=common.Config.MustValue("config","seckill_time","2") + seckillTime,_:=strconv.Atoi(str) + seckillTotalTime:=time.Now().Add(time.Duration(seckillTime)*time.Minute).Unix() + //抢购间隔时间读取配置文件 + str=common.Config.MustValue("config","ticker_time","1500") + tickerTime,_:=strconv.Atoi(str) //开始检测抢购状态 go CheckSeckillStatus() - //抢购总时间两分钟,超时程序自动退出 + //抢购总时间超时程序自动退出 for time.Now().Unix() Date: Mon, 4 Jan 2021 22:05:06 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E5=BC=95=E8=B5=B7=E6=8A=A2=E8=B4=AD=E9=93=BE=E6=8E=A5=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jd_seckill/seckill.go | 27 +++++++++++++++++++++------ jd_seckill/user.go | 7 ++++++- main.go | 4 ---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/jd_seckill/seckill.go b/jd_seckill/seckill.go index e493eff..8be8e04 100644 --- a/jd_seckill/seckill.go +++ b/jd_seckill/seckill.go @@ -79,7 +79,8 @@ func (this *Seckill) getSeckillUrl() (string, error) { _, body, _ := req.Send().End() //临时打印数据 log.Println("返回信息:"+body) - var cbBody string + //先注释,测试过gjson可以解析jQuery1153906({"type":"3","state":"13","url":""})格式 +/* var cbBody string cbBody = body spBody := strings.Split(body, "(") if len(spBody) >= 2 { @@ -89,6 +90,10 @@ func (this *Seckill) getSeckillUrl() (string, error) { if gjson.Get(cbBody, "url").Exists() && gjson.Get(cbBody, "url").String() != "" { url = gjson.Get(cbBody, "url").String() break + }*/ + if gjson.Get(body, "url").Exists() && gjson.Get(body, "url").String() != "" { + url = gjson.Get(body, "url").String() + break } log.Println("抢购链接获取失败,稍后自动重试") time.Sleep(300 * time.Millisecond) @@ -115,7 +120,12 @@ func (this *Seckill) RequestSeckillUrl() { url, _ := this.getSeckillUrl() skuId := this.conf.MustValue("config", "sku_id", "") log.Println("访问商品的抢购连接...") - req := httpc.NewRequest(this.client) + client:=httpc.NewHttpClient() + client.SetCookieJar(common.CookieJar) + client.SetRedirect(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }) + req := httpc.NewRequest(client) req.SetHeader("User-Agent", this.getUserAgent()) req.SetHeader("Host", "marathon.jd.com") req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) @@ -125,8 +135,13 @@ func (this *Seckill) RequestSeckillUrl() { func (this *Seckill) SeckillPage() { log.Println("访问抢购订单结算页面...") skuId := this.conf.MustValue("config", "sku_id", "") - seckillNum := this.conf.MustValue("config", "seckill_num", "") - req := httpc.NewRequest(this.client) + seckillNum := this.conf.MustValue("config", "seckill_num", "2") + client:=httpc.NewHttpClient() + client.SetCookieJar(common.CookieJar) + client.SetRedirect(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }) + req := httpc.NewRequest(client) req.SetHeader("User-Agent", this.getUserAgent()) req.SetHeader("Host", "marathon.jd.com") req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId)) @@ -136,7 +151,7 @@ func (this *Seckill) SeckillPage() { func (this *Seckill) SeckillInitInfo() (string, error) { log.Println("获取秒杀初始化信息...") skuId := this.conf.MustValue("config", "sku_id", "") - seckillNum := this.conf.MustValue("config", "seckill_num", "") + seckillNum := this.conf.MustValue("config", "seckill_num", "2") req := httpc.NewRequest(this.client) req.SetHeader("User-Agent", this.getUserAgent()) req.SetHeader("Host", "marathon.jd.com") @@ -159,7 +174,7 @@ func (this *Seckill) SubmitSeckillOrder() bool { eid := this.conf.MustValue("config", "eid", "") fp := this.conf.MustValue("config", "fp", "") skuId := this.conf.MustValue("config", "sku_id", "") - seckillNum := this.conf.MustValue("config", "seckill_num", "") + seckillNum := this.conf.MustValue("config", "seckill_num", "2") paymentPwd := this.conf.MustValue("account", "payment_pwd", "") initInfo, err := this.SeckillInitInfo() if err != nil { diff --git a/jd_seckill/user.go b/jd_seckill/user.go index 85fd987..2a86d06 100644 --- a/jd_seckill/user.go +++ b/jd_seckill/user.go @@ -97,7 +97,12 @@ func (this *User) TicketInfo(ticket string) (string,error) { } func (this *User) RefreshStatus() error { - req:=httpc.NewRequest(this.client) + client:=httpc.NewHttpClient() + client.SetCookieJar(common.CookieJar) + client.SetRedirect(func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }) + req:=httpc.NewRequest(client) req.SetHeader("User-Agent",this.getUserAgent()) resp,_,err:=req.SetUrl("https://order.jd.com/center/list.action?rid="+strconv.Itoa(int(time.Now().Unix()*1000))).SetMethod("get").Send().End() if err==nil && resp.StatusCode==http.StatusOK { diff --git a/main.go b/main.go index 71a77e2..1dd52b9 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ import ( "github.com/ztino/jd_seckill/cmd" "github.com/ztino/jd_seckill/common" "log" - "net/http" "os" "runtime" ) @@ -16,9 +15,6 @@ func init() { common.Client=httpc.NewHttpClient() common.CookieJar=httpc.NewCookieJar() common.Client.SetCookieJar(common.CookieJar) - common.Client.SetRedirect(func(req *http.Request, via []*http.Request) error { - return http.ErrUseLastResponse - }) //配置文件初始化 confFile:="./conf.ini" From be17fdeb51de9482ab7a6f4cd6ff6f82011b4750 Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 23:57:30 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=8E=B7=E5=8F=96eid?= =?UTF-8?q?=E5=92=8Cfp=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/jdTdudfp.go | 51 +++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/cmd/jdTdudfp.go b/cmd/jdTdudfp.go index eb1c676..329efd3 100644 --- a/cmd/jdTdudfp.go +++ b/cmd/jdTdudfp.go @@ -11,8 +11,6 @@ import ( "github.com/ztino/jd_seckill/common" "github.com/ztino/jd_seckill/jd_seckill" "log" - "net/http" - "net/http/httptest" "net/url" "time" ) @@ -34,16 +32,20 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { log.Println("自动获取eid和fp失败,请重新登录") }else { log.Println("开始自动获取eid和fp,如遇卡住请结束进程,重新启动") - ctx := context.Background() options := []chromedp.ExecAllocatorOption{ chromedp.Flag("headless", false), - chromedp.Flag("hide-scrollbars", false), - chromedp.Flag("mute-audio", false), + //chromedp.Flag("blink-settings", "imagesEnabled=false"), + chromedp.Flag("start-maximized", true), + chromedp.Flag("no-sandbox",true), + chromedp.Flag("disable-setuid-sandbox",true), + chromedp.Flag("no-default-browser-check",true), + chromedp.Flag("disable-plugins",true), + chromedp.WindowSize(1920,1080), chromedp.UserAgent(common.Config.MustValue("config","default_user_agent","")), } options = append(chromedp.DefaultExecAllocatorOptions[:], options...) - c, cc := chromedp.NewExecAllocator(ctx, options...) + c, cc := chromedp.NewExecAllocator(context.Background(), options...) defer cc() ctx, cancel := chromedp.NewContext(c) @@ -52,7 +54,7 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { u, _ := url.Parse("http://jd.com") cookies := common.CookieJar.Cookies(u) - err := chromedp.Run(ctx, + err = chromedp.Run(ctx, chromedp.Tasks{ chromedp.ActionFunc(func(ctx context.Context) error { expr := cdp.TimeSinceEpoch(time.Now().Add(180 * 24 * time.Hour)) @@ -66,42 +68,46 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { return nil }), chromedp.Navigate("https://jd.com"), + chromedp.Sleep(2*time.Second), chromedp.Click(".cate_menu_lk"), + chromedp.Sleep(2*time.Second), }, ) if err != nil { log.Fatal(err) } - newCtx, cancel := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch)) - ch = addNewTabListener(newCtx) - defer cancel() + + newCtx, cancel2 := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch)) + ch2 := addNewTabListener(newCtx) + defer cancel2() err = chromedp.Run(newCtx, - chromedp.Click(`.goods_item_link`), + chromedp.Click(".goods_item_link"), + chromedp.Sleep(4*time.Second), ) if err != nil { log.Fatal(err) } - newCtx, cancel = chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch)) - defer cancel() + newCtx2, cancel3 := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch2)) + defer cancel3() var res []byte - err = chromedp.Run(newCtx, - chromedp.Click(`#InitCartUrl`), - chromedp.WaitVisible(".btn-addtocart"), + err = chromedp.Run(newCtx2, + chromedp.Click("#InitCartUrl"), + chromedp.Sleep(2*time.Second), chromedp.Click(".btn-addtocart"), - chromedp.WaitVisible(".common-submit-btn"), + chromedp.Sleep(2*time.Second), chromedp.Click(".common-submit-btn"), - chromedp.WaitVisible("#sumPayPriceId"), chromedp.Sleep(3*time.Second), chromedp.Evaluate("_JdTdudfp", &res), ) if err != nil { log.Fatal(err) } + value:=string(res) - if !gjson.Valid(value) { + if !gjson.Valid(value) || gjson.Get(value,"eid").String()=="" || gjson.Get(value,"fp").String()=="" { log.Println("获取失败,请重新尝试,返回信息:"+value) }else{ log.Println("获取成功,请手动填入配置文件") @@ -112,11 +118,10 @@ func startJdTdudfp(cmd *cobra.Command, args []string) { } func addNewTabListener(ctx context.Context) <-chan target.ID { - mux := http.NewServeMux() +/* mux := http.NewServeMux() ts := httptest.NewServer(mux) - defer ts.Close() - + defer ts.Close()*/ return chromedp.WaitNewTarget(ctx, func(info *target.Info) bool { - return info.URL != "" + return true }) } \ No newline at end of file From f4efbaafe8255063eb62f251c3fa716c7d4c451b Mon Sep 17 00:00:00 2001 From: ztino <> Date: Mon, 4 Jan 2021 23:58:57 +0800 Subject: [PATCH 9/9] release 0.1.7 --- common/var.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/var.go b/common/var.go index dfee626..023779c 100644 --- a/common/var.go +++ b/common/var.go @@ -7,7 +7,7 @@ import ( const SoftName = "jd_seckill" -const Version = "0.1.6" +const Version = "0.1.7" var Client *httpc.HttpClient