Browse Source

Merge branch 'main' of https://github.com/ztino/jd_seckill into main

 Conflicts:
	conf.ini
main
燕鹏 4 years ago
parent
commit
7fb7c9f55e
  1. 14
      README.md
  2. 55
      cmd/jdTdudfp.go
  3. 19
      cmd/seckill.go
  4. 2
      cmd/version.go
  5. 2
      common/var.go
  6. 10
      conf.ini
  7. 341
      jd_seckill/seckill.go
  8. 7
      jd_seckill/user.go
  9. 4
      main.go

14
README.md

@ -10,6 +10,16 @@ Jd_Seckill
## 安装 ## 安装
方式一(推荐):
```shell
git clone https://github.com/ztino/jd_seckill.git
cd jd_seckill
go get
```
方式二:
```shell ```shell
go get github.com/ztino/jd_seckill go get github.com/ztino/jd_seckill
``` ```
@ -32,7 +42,7 @@ go get github.com/ztino/jd_seckill
jd_seckill login jd_seckill login
``` ```
### 自动获取eif,fp ### 自动获取eid,fp
> ⚠依赖谷歌浏览器,请安装谷歌浏览器,获取到的eid和fp请手动填入配置文件 > ⚠依赖谷歌浏览器,请安装谷歌浏览器,获取到的eid和fp请手动填入配置文件
@ -40,7 +50,7 @@ jd_seckill login
```shell ```shell
jd_seckill jdTdudfp jd_seckill jdTdudfp
``` ```
> ⚠目前测试阶段,请勿依赖该功能 > ⚠目前实验性阶段,请勿依赖该功能
### 预约 ### 预约
执行以下命令按照提示操作: 执行以下命令按照提示操作:

55
cmd/jdTdudfp.go

@ -11,8 +11,6 @@ import (
"github.com/ztino/jd_seckill/common" "github.com/ztino/jd_seckill/common"
"github.com/ztino/jd_seckill/jd_seckill" "github.com/ztino/jd_seckill/jd_seckill"
"log" "log"
"net/http"
"net/http/httptest"
"net/url" "net/url"
"time" "time"
) )
@ -34,16 +32,20 @@ func startJdTdudfp(cmd *cobra.Command, args []string) {
log.Println("自动获取eid和fp失败,请重新登录") log.Println("自动获取eid和fp失败,请重新登录")
}else { }else {
log.Println("开始自动获取eid和fp,如遇卡住请结束进程,重新启动") log.Println("开始自动获取eid和fp,如遇卡住请结束进程,重新启动")
ctx := context.Background()
options := []chromedp.ExecAllocatorOption{ options := []chromedp.ExecAllocatorOption{
chromedp.Flag("headless", false), chromedp.Flag("headless", false),
chromedp.Flag("hide-scrollbars", false), //chromedp.Flag("blink-settings", "imagesEnabled=false"),
chromedp.Flag("mute-audio", 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","")), chromedp.UserAgent(common.Config.MustValue("config","default_user_agent","")),
} }
options = append(chromedp.DefaultExecAllocatorOptions[:], options...) options = append(chromedp.DefaultExecAllocatorOptions[:], options...)
c, cc := chromedp.NewExecAllocator(ctx, options...) c, cc := chromedp.NewExecAllocator(context.Background(), options...)
defer cc() defer cc()
ctx, cancel := chromedp.NewContext(c) ctx, cancel := chromedp.NewContext(c)
@ -52,7 +54,7 @@ func startJdTdudfp(cmd *cobra.Command, args []string) {
u, _ := url.Parse("http://jd.com") u, _ := url.Parse("http://jd.com")
cookies := common.CookieJar.Cookies(u) cookies := common.CookieJar.Cookies(u)
err := chromedp.Run(ctx, err = chromedp.Run(ctx,
chromedp.Tasks{ chromedp.Tasks{
chromedp.ActionFunc(func(ctx context.Context) error { chromedp.ActionFunc(func(ctx context.Context) error {
expr := cdp.TimeSinceEpoch(time.Now().Add(180 * 24 * time.Hour)) expr := cdp.TimeSinceEpoch(time.Now().Add(180 * 24 * time.Hour))
@ -66,43 +68,47 @@ func startJdTdudfp(cmd *cobra.Command, args []string) {
return nil return nil
}), }),
chromedp.Navigate("https://jd.com"), chromedp.Navigate("https://jd.com"),
chromedp.Sleep(2*time.Second),
chromedp.Click(".cate_menu_lk"), chromedp.Click(".cate_menu_lk"),
chromedp.Sleep(2*time.Second),
}, },
) )
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
newCtx, cancel := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch))
ch = addNewTabListener(newCtx) newCtx, cancel2 := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch))
defer cancel() ch2 := addNewTabListener(newCtx)
defer cancel2()
err = chromedp.Run(newCtx, err = chromedp.Run(newCtx,
chromedp.Click(`.goods_item_link`), chromedp.Click(".goods_item_link"),
chromedp.Sleep(4*time.Second),
) )
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
newCtx, cancel = chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch)) newCtx2, cancel3 := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch2))
defer cancel() defer cancel3()
var res []byte var res []byte
err = chromedp.Run(newCtx, err = chromedp.Run(newCtx2,
chromedp.Click(`#InitCartUrl`), chromedp.Click("#InitCartUrl"),
chromedp.WaitVisible(".btn-addtocart"), chromedp.Sleep(2*time.Second),
chromedp.Click(".btn-addtocart"), chromedp.Click(".btn-addtocart"),
chromedp.WaitVisible(".common-submit-btn"),
chromedp.Click(".common-submit-btn"),
chromedp.WaitVisible("#sumPayPriceId"),
chromedp.Sleep(2*time.Second), chromedp.Sleep(2*time.Second),
chromedp.Click(".common-submit-btn"),
chromedp.Sleep(3*time.Second),
chromedp.Evaluate("_JdTdudfp", &res), chromedp.Evaluate("_JdTdudfp", &res),
) )
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
value:=string(res) value:=string(res)
if !gjson.Valid(value) { if !gjson.Valid(value) || gjson.Get(value,"eid").String()=="" || gjson.Get(value,"fp").String()=="" {
log.Println("获取失败,请重新尝试") log.Println("获取失败,请重新尝试,返回信息:"+value)
}else{ }else{
log.Println("获取成功,请手动填入配置文件") log.Println("获取成功,请手动填入配置文件")
log.Println("eid:"+gjson.Get(value,"eid").String()) log.Println("eid:"+gjson.Get(value,"eid").String())
@ -112,11 +118,10 @@ func startJdTdudfp(cmd *cobra.Command, args []string) {
} }
func addNewTabListener(ctx context.Context) <-chan target.ID { func addNewTabListener(ctx context.Context) <-chan target.ID {
mux := http.NewServeMux() /* mux := http.NewServeMux()
ts := httptest.NewServer(mux) ts := httptest.NewServer(mux)
defer ts.Close() defer ts.Close()*/
return chromedp.WaitNewTarget(ctx, func(info *target.Info) bool { return chromedp.WaitNewTarget(ctx, func(info *target.Info) bool {
return info.URL != "" return true
}) })
} }

19
cmd/seckill.go

@ -11,6 +11,7 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"strconv"
"time" "time"
) )
@ -54,7 +55,10 @@ func startSeckill(cmd *cobra.Command, args []string) {
seckill:=jd_seckill.NewSeckill(common.Client,common.Config) 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) { 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() go CheckSeckillStatus()
//抢购总时间两分钟,超时程序自动退出 //抢购总时间超时程序自动退出
for time.Now().Unix()<seckillTotalTime { for time.Now().Unix()<seckillTotalTime {
for i:=1;i<=taskNum;i++ { for i:=1;i<=taskNum;i++ {
go task(seckill) go task(seckill)
} }
//每隔1.5秒执行一次
//怕封号的可以增加间隔时间,相反抢到的成功率也减低了 //怕封号的可以增加间隔时间,相反抢到的成功率也减低了
time.Sleep(1500*time.Millisecond) time.Sleep(time.Duration(tickerTime)*time.Millisecond)
} }
log.Println("抢购结束,具体详情请查看日志") log.Println("抢购结束,具体详情请查看日志")
} }

2
cmd/version.go

@ -15,6 +15,6 @@ var versionCmd = &cobra.Command{
Use: "version", Use: "version",
Short: "Print the version number of jd_seckill", Short: "Print the version number of jd_seckill",
Run: func(cmd *cobra.Command, args []string) { 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))
}, },
} }

2
common/var.go

@ -7,7 +7,7 @@ import (
const SoftName = "jd_seckill" const SoftName = "jd_seckill"
const Version = "0.1.6" const Version = "0.1.7"
var Client *httpc.HttpClient var Client *httpc.HttpClient

10
conf.ini

@ -9,8 +9,14 @@ fp = 6daf4b091e8dc5d67632c682ac086a81
sku_id = 100012043978 sku_id = 100012043978
# 抢购数量 # 抢购数量
seckill_num = 2 seckill_num = 2
# 设定时间 # 2020-12-09 10:00:00.100000 # 抢购开始时间设定 2021-01-01 09:59:59
buy_time = 2021-01-05 09:59:59 buy_time = 2021-01-01 09:59:59
# 抢购总时间,单位:分钟,默认两分钟
seckill_time =
# 抢购任务数量,默认5个
task_num =
# 每次抢购间隔时间,单位:毫秒,默认1500毫秒,每1000毫秒等于1秒
ticker_time =
# 默认UA # 默认UA
default_user_agent = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36 default_user_agent = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36

341
jd_seckill/seckill.go

@ -18,217 +18,244 @@ import (
type Seckill struct { type Seckill struct {
client *httpc.HttpClient client *httpc.HttpClient
conf *goconfig.ConfigFile conf *goconfig.ConfigFile
} }
func NewSeckill(client *httpc.HttpClient,conf *goconfig.ConfigFile) *Seckill { func NewSeckill(client *httpc.HttpClient, conf *goconfig.ConfigFile) *Seckill {
return &Seckill{client: client,conf: conf} return &Seckill{client: client, conf: conf}
} }
func (this *Seckill) getUserAgent() string { 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) { func (this *Seckill) SkuTitle() (string, error) {
skuId:=this.conf.MustValue("config","sku_id","") skuId := this.conf.MustValue("config", "sku_id", "")
req:=httpc.NewRequest(this.client) req := httpc.NewRequest(this.client)
resp,body,err:=req.SetUrl(fmt.Sprintf("https://item.jd.com/%s.html",skuId)).SetMethod("get").Send().End() 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 { if err != nil || resp.StatusCode != http.StatusOK {
log.Println("访问商品详情失败") log.Println("访问商品详情失败")
return "",errors.New("访问商品详情失败") return "", errors.New("访问商品详情失败")
} }
html:=strings.NewReader(body) html := strings.NewReader(body)
doc,_:=goquery.NewDocumentFromReader(html) doc, _ := goquery.NewDocumentFromReader(html)
return strings.TrimSpace(doc.Find(".sku-name").Text()),nil return strings.TrimSpace(doc.Find(".sku-name").Text()), nil
} }
func (this *Seckill) MakeReserve() { func (this *Seckill) MakeReserve() {
user:=NewUser(this.client,this.conf) user := NewUser(this.client, this.conf)
userInfo,_:=user.GetUserInfo() userInfo, _ := user.GetUserInfo()
log.Println("用户:"+userInfo) log.Println("用户:" + userInfo)
shopTitle,err:=this.SkuTitle() shopTitle, err := this.SkuTitle()
if err!=nil { if err != nil {
log.Println("获取商品信息失败") log.Println("获取商品信息失败")
}else{ } else {
log.Println("商品名称:"+shopTitle) log.Println("商品名称:" + shopTitle)
} }
skuId:=this.conf.MustValue("config","sku_id","") skuId := this.conf.MustValue("config", "sku_id", "")
req:=httpc.NewRequest(this.client) req := httpc.NewRequest(this.client)
req.SetHeader("User-Agent",this.getUserAgent()) req.SetHeader("User-Agent", this.getUserAgent())
req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) 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() 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 { if err != nil || resp.StatusCode != http.StatusOK {
log.Println("预约商品失败") log.Println("预约商品失败")
}else{ } else {
reserveUrl:=gjson.Get(body,"url").String() reserveUrl := gjson.Get(body, "url").String()
req=httpc.NewRequest(this.client) req = httpc.NewRequest(this.client)
_,_,_=req.SetUrl("https:"+reserveUrl).SetMethod("get").Send().End() _, _, _ = req.SetUrl("https:" + reserveUrl).SetMethod("get").Send().End()
log.Println("预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约") log.Println("预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约")
} }
} }
func (this *Seckill) getSeckillUrl() (string,error) { func (this *Seckill) getSeckillUrl() (string, error) {
skuId:=this.conf.MustValue("config","sku_id","") skuId := this.conf.MustValue("config", "sku_id", "")
req:=httpc.NewRequest(this.client) req := httpc.NewRequest(this.client)
req.SetHeader("User-Agent",this.getUserAgent()) req.SetHeader("User-Agent", this.getUserAgent())
req.SetHeader("Host","itemko.jd.com") req.SetHeader("Host", "itemko.jd.com")
req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) req.SetHeader("Referer", fmt.Sprintf("https://item.jd.com/%s.html", skuId))
url:="" 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")
for { url := ""
_,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() for {
if gjson.Get(body,"url").Exists() && gjson.Get(body,"url").String()!="" { _, body, _ := req.Send().End()
url=gjson.Get(body,"url").String() //临时打印数据
log.Println("返回信息:"+body)
//先注释,测试过gjson可以解析jQuery1153906({"type":"3","state":"13","url":""})格式
/* 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
}*/
if gjson.Get(body, "url").Exists() && gjson.Get(body, "url").String() != "" {
url = gjson.Get(body, "url").String()
break break
} }
log.Println("抢购链接获取失败,稍后自动重试") log.Println("抢购链接获取失败,稍后自动重试")
time.Sleep(300*time.Millisecond) time.Sleep(300 * time.Millisecond)
} }
url = "https:"+url
//https://divide.jd.com/user_routing?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc //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 //https://marathon.jd.com/captcha.html?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc
url=strings.ReplaceAll(url,"user_routing","captcha.html") url = strings.ReplaceAll(url, "user_routing", "captcha.html")
log.Println("抢购链接获取成功:"+url) log.Println("抢购链接获取成功:" + url)
return url,nil return url, nil
} }
func (this *Seckill) RequestSeckillUrl() { func (this *Seckill) RequestSeckillUrl() {
user:=NewUser(this.client,this.conf) user := NewUser(this.client, this.conf)
userInfo,_:=user.GetUserInfo() userInfo, _ := user.GetUserInfo()
log.Println("用户:"+userInfo) log.Println("用户:" + userInfo)
shopTitle,err:=this.SkuTitle() shopTitle, err := this.SkuTitle()
if err!=nil { if err != nil {
log.Println("获取商品信息失败") log.Println("获取商品信息失败")
}else{ } else {
log.Println("商品名称:"+shopTitle) log.Println("商品名称:" + shopTitle)
} }
url,_:=this.getSeckillUrl() url, _ := this.getSeckillUrl()
skuId:=this.conf.MustValue("config","sku_id","") skuId := this.conf.MustValue("config", "sku_id", "")
req:=httpc.NewRequest(this.client) log.Println("访问商品的抢购连接...")
req.SetHeader("User-Agent",this.getUserAgent()) client:=httpc.NewHttpClient()
req.SetHeader("Host","marathon.jd.com") client.SetCookieJar(common.CookieJar)
req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) client.SetRedirect(func(req *http.Request, via []*http.Request) error {
_,_,_=req.SetUrl(url).SetMethod("get").Send().End() 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))
_, _, _ = req.SetUrl(url).SetMethod("get").Send().End()
} }
func (this *Seckill) SeckillPage() { func (this *Seckill) SeckillPage() {
log.Println("访问抢购订单结算页面...") log.Println("访问抢购订单结算页面...")
skuId:=this.conf.MustValue("config","sku_id","") 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) client:=httpc.NewHttpClient()
req.SetHeader("User-Agent",this.getUserAgent()) client.SetCookieJar(common.CookieJar)
req.SetHeader("Host","marathon.jd.com") client.SetRedirect(func(req *http.Request, via []*http.Request) error {
req.SetHeader("Referer",fmt.Sprintf("https://item.jd.com/%s.html",skuId)) return http.ErrUseLastResponse
_,_,_=req.SetUrl("https://marathon.jd.com/seckill/seckill.action?skuId="+skuId+"&num="+seckillNum+"&rid="+strconv.Itoa(int(time.Now().Unix()))).SetMethod("get").Send().End() })
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))
_, _, _ = 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("获取秒杀初始化信息...") log.Println("获取秒杀初始化信息...")
skuId:=this.conf.MustValue("config","sku_id","") 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 := httpc.NewRequest(this.client)
req.SetHeader("User-Agent",this.getUserAgent()) req.SetHeader("User-Agent", this.getUserAgent())
req.SetHeader("Host","marathon.jd.com") req.SetHeader("Host", "marathon.jd.com")
req.SetData("sku",skuId) req.SetData("sku", skuId)
req.SetData("num",seckillNum) req.SetData("num", seckillNum)
req.SetData("isModifyAddress","false") req.SetData("isModifyAddress", "false")
resp,body,err:=req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/init.action").SetMethod("post").Send().End() 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 { if err != nil || resp.StatusCode != http.StatusOK {
log.Println("初始化秒杀信息失败") log.Println("初始化秒杀信息失败")
return "",errors.New("初始化秒杀信息失败") return "", errors.New("初始化秒杀信息失败")
} }
if !gjson.Valid(body) { if !gjson.Valid(body) {
log.Println("抢购失败,返回信息:"+body) log.Println("抢购失败,返回信息:" + body)
return "", errors.New("抢购失败,返回信息:"+body) return "", errors.New("抢购失败,返回信息:" + body)
} }
return body,nil return body, nil
} }
func (this *Seckill) SubmitSeckillOrder() bool { func (this *Seckill) SubmitSeckillOrder() bool {
eid:=this.conf.MustValue("config","eid","") eid := this.conf.MustValue("config", "eid", "")
fp:=this.conf.MustValue("config","fp","") fp := this.conf.MustValue("config", "fp", "")
skuId:=this.conf.MustValue("config","sku_id","") 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","") paymentPwd := this.conf.MustValue("account", "payment_pwd", "")
initInfo,err:=this.SeckillInitInfo() initInfo, err := this.SeckillInitInfo()
if err!=nil { if err != nil {
log.Println(fmt.Sprintf("抢购失败,无法获取生成订单的基本信息,接口返回:【%s】",err.Error())) log.Println(fmt.Sprintf("抢购失败,无法获取生成订单的基本信息,接口返回:【%s】", err.Error()))
return false return false
} }
address:=gjson.Get(initInfo,"addressList").Array() address := gjson.Get(initInfo, "addressList").Array()
defaultAddress:=address[0] defaultAddress := address[0]
isinvoiceInfo:=gjson.Get(initInfo,"invoiceInfo").Exists() isinvoiceInfo := gjson.Get(initInfo, "invoiceInfo").Exists()
invoiceTitle:="-1" invoiceTitle := "-1"
invoiceContentType:="-1" invoiceContentType := "-1"
invoicePhone:="" invoicePhone := ""
invoicePhoneKey:="" invoicePhoneKey := ""
invoiceInfo:="false" invoiceInfo := "false"
if isinvoiceInfo { if isinvoiceInfo {
invoiceTitle=gjson.Get(initInfo,"invoiceInfo.invoiceTitle").String() invoiceTitle = gjson.Get(initInfo, "invoiceInfo.invoiceTitle").String()
invoiceContentType=gjson.Get(initInfo,"invoiceInfo.invoiceContentType").String() invoiceContentType = gjson.Get(initInfo, "invoiceInfo.invoiceContentType").String()
invoicePhone=gjson.Get(initInfo,"invoiceInfo.invoicePhone").String() invoicePhone = gjson.Get(initInfo, "invoiceInfo.invoicePhone").String()
invoicePhoneKey=gjson.Get(initInfo,"invoiceInfo.invoicePhoneKey").String() invoicePhoneKey = gjson.Get(initInfo, "invoiceInfo.invoicePhoneKey").String()
invoiceInfo="true" invoiceInfo = "true"
} }
token:=gjson.Get(initInfo,"token").String() token := gjson.Get(initInfo, "token").String()
log.Println("提交抢购订单...") log.Println("提交抢购订单...")
req:=httpc.NewRequest(this.client) req := httpc.NewRequest(this.client)
req.SetHeader("User-Agent",this.getUserAgent()) req.SetHeader("User-Agent", this.getUserAgent())
req.SetHeader("Host","marathon.jd.com") 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.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("skuId", skuId)
req.SetData("num",seckillNum) req.SetData("num", seckillNum)
req.SetData("addressId",defaultAddress.Get("id").String()) req.SetData("addressId", defaultAddress.Get("id").String())
req.SetData("yuShou","true") req.SetData("yuShou", "true")
req.SetData("isModifyAddress","false") req.SetData("isModifyAddress", "false")
req.SetData("name",defaultAddress.Get("name").String()) req.SetData("name", defaultAddress.Get("name").String())
req.SetData("provinceId",defaultAddress.Get("provinceId").String()) req.SetData("provinceId", defaultAddress.Get("provinceId").String())
req.SetData("cityId",defaultAddress.Get("cityId").String()) req.SetData("cityId", defaultAddress.Get("cityId").String())
req.SetData("countyId",defaultAddress.Get("countyId").String()) req.SetData("countyId", defaultAddress.Get("countyId").String())
req.SetData("townId",defaultAddress.Get("townId").String()) req.SetData("townId", defaultAddress.Get("townId").String())
req.SetData("addressDetail",defaultAddress.Get("addressDetail").String()) req.SetData("addressDetail", defaultAddress.Get("addressDetail").String())
req.SetData("mobile",defaultAddress.Get("mobile").String()) req.SetData("mobile", defaultAddress.Get("mobile").String())
req.SetData("mobileKey",defaultAddress.Get("mobileKey").String()) req.SetData("mobileKey", defaultAddress.Get("mobileKey").String())
req.SetData("email",defaultAddress.Get("email").String()) req.SetData("email", defaultAddress.Get("email").String())
req.SetData("postCode","") req.SetData("postCode", "")
req.SetData("invoiceTitle",invoiceTitle) req.SetData("invoiceTitle", invoiceTitle)
req.SetData("invoiceCompanyName","") req.SetData("invoiceCompanyName", "")
req.SetData("invoiceContent",invoiceContentType) req.SetData("invoiceContent", invoiceContentType)
req.SetData("invoiceTaxpayerNO","") req.SetData("invoiceTaxpayerNO", "")
req.SetData("invoiceEmail","") req.SetData("invoiceEmail", "")
req.SetData("invoicePhone",invoicePhone) req.SetData("invoicePhone", invoicePhone)
req.SetData("invoicePhoneKey",invoicePhoneKey) req.SetData("invoicePhoneKey", invoicePhoneKey)
req.SetData("invoice",invoiceInfo) req.SetData("invoice", invoiceInfo)
req.SetData("password",paymentPwd) req.SetData("password", paymentPwd)
req.SetData("codTimeType","3") req.SetData("codTimeType", "3")
req.SetData("paymentType","4") req.SetData("paymentType", "4")
req.SetData("areaCode","") req.SetData("areaCode", "")
req.SetData("overseas","0") req.SetData("overseas", "0")
req.SetData("phone","") req.SetData("phone", "")
req.SetData("eid",eid) req.SetData("eid", eid)
req.SetData("fp",fp) req.SetData("fp", fp)
req.SetData("token",token) req.SetData("token", token)
req.SetData("pru","") req.SetData("pru", "")
resp,body,err:=req.SetUrl("https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action?skuId="+skuId).SetMethod("post").Send().End() 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 { if err != nil || resp.StatusCode != http.StatusOK {
log.Println("抢购失败,网络错误") log.Println("抢购失败,网络错误")
_=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,网络错误") _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,网络错误")
return false return false
} }
if !gjson.Valid(body) { if !gjson.Valid(body) {
log.Println("抢购失败,返回信息:"+body) log.Println("抢购失败,返回信息:" + body)
_=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,返回信息:"+body) _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,返回信息:"+body)
return false return false
} }
if gjson.Get(body,"success").Bool() { if gjson.Get(body, "success").Bool() {
orderId:=gjson.Get(body,"orderId").String() orderId := gjson.Get(body, "orderId").String()
totalMoney:=gjson.Get(body,"totalMoney").String() totalMoney := gjson.Get(body, "totalMoney").String()
payUrl:="https:"+gjson.Get(body,"pcUrl").String() payUrl := "https:" + gjson.Get(body, "pcUrl").String()
log.Println(fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s",orderId,totalMoney,payUrl)) log.Println(fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s", orderId, totalMoney, payUrl))
_=service.SendMessage(this.conf,"茅台抢购通知",fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s",orderId,totalMoney,payUrl)) _ = service.SendMessage(this.conf, "茅台抢购通知", fmt.Sprintf("抢购成功,订单号:%s, 总价:%s, 电脑端付款链接:%s", orderId, totalMoney, payUrl))
return true return true
}else{ } else {
log.Println("抢购失败,返回信息:"+body) log.Println("抢购失败,返回信息:" + body)
_=service.SendMessage(this.conf,"茅台抢购通知","抢购失败,返回信息:"+body) _ = service.SendMessage(this.conf, "茅台抢购通知", "抢购失败,返回信息:"+body)
return false return false
} }
} }

7
jd_seckill/user.go

@ -97,7 +97,12 @@ func (this *User) TicketInfo(ticket string) (string,error) {
} }
func (this *User) RefreshStatus() 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()) 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() 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 { if err==nil && resp.StatusCode==http.StatusOK {

4
main.go

@ -6,7 +6,6 @@ import (
"github.com/ztino/jd_seckill/cmd" "github.com/ztino/jd_seckill/cmd"
"github.com/ztino/jd_seckill/common" "github.com/ztino/jd_seckill/common"
"log" "log"
"net/http"
"os" "os"
"runtime" "runtime"
) )
@ -16,9 +15,6 @@ func init() {
common.Client=httpc.NewHttpClient() common.Client=httpc.NewHttpClient()
common.CookieJar=httpc.NewCookieJar() common.CookieJar=httpc.NewCookieJar()
common.Client.SetCookieJar(common.CookieJar) common.Client.SetCookieJar(common.CookieJar)
common.Client.SetRedirect(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
})
//配置文件初始化 //配置文件初始化
confFile:="./conf.ini" confFile:="./conf.ini"

Loading…
Cancel
Save