Skip to content

Commit

Permalink
Feat: 新增从购物车抢购流程
Browse files Browse the repository at this point in the history
  • Loading branch information
meooxx committed Nov 29, 2020
1 parent 7f3ce0d commit 9d19da0
Show file tree
Hide file tree
Showing 45 changed files with 47,586 additions and 69 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
cookie.json
node_modules
config.js
*.log
*.log
qrcode.png
108 changes: 67 additions & 41 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@

# 买 jd 直营口罩

### 此代码基于原作者 https://github.com/tychxn/jd-assistan 进行修改

## 单独支持预约-抢购-成功后直接提交订单的商品

**疫情期间, 口罩资源空缺, 没得办法(不作恶)**
狗东现有俩种抢购模式

1. 到时间直接抢购(例如口罩)
2. 到时间先添加购物车->到购物车提交订单(显卡)
3. _请一定要搞清楚使用哪种模式, 否则抢不到_

## Quick Start

Expand All @@ -14,31 +17,33 @@
```js
// 最简单只加 eid 和 fp
const config = {
// 支持自定义 UA
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
// 是否微信公众号推送抢购结果, 非必填
messenger: true, // true, false
// key值在 https://sc.ftqq.com/3.version 查看申请使用的方法, 把key粘贴至这里, 关注网站中公众号即可
sckey: '', // string, messenger 有则为必填, 不填写不影响抢购流程

// 必填,
// 方式1: jd登录 pc 端, 随便提交一个订单,利用谷歌浏览器devtools, 选择 `network`,
// 查看 submitOrder (注意要勾选 preserve log, 否则提交订单跳转后看不到该接口了) 接
// 口, 把接口提交的数据里面的 `eid`, 和 `fp` 俩个字段分别粘贴过来
// 方式2: 或者电脑打开jd登陆页面, devtools, 选择 `Elements`, 搜索 eid 和 sessionId(即fp), 在搜索到的input元素上面
// value 属性中的值复制过来
eid: '', // string, 必填
fp: '' // string, 必填
// 支持自定义 UA
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
// 是否微信公众号推送抢购结果, 非必填
messenger: true, // true, false
// key值在 https://sc.ftqq.com/3.version 查看申请使用的方法, 把key粘贴至这里, 关注网站中公众号即可
sckey: '', // string, messenger 有则为必填, 不填写不影响抢购流程

// 必填,
// 方式1: jd登录 pc 端, 随便提交一个订单,利用谷歌浏览器devtools, 选择 `network`,
// 查看 submitOrder (注意要勾选 preserve log, 否则提交订单跳转后看不到该接口了) 接
// 口, 把接口提交的数据里面的 `eid`, 和 `fp` 俩个字段分别粘贴过来
// 方式2: 或者电脑打开jd登陆页面, devtools, 选择 `Elements`, 搜索 eid 和 sessionId(即fp), 在搜索到的input元素上面
// value 属性中的值复制过来
eid: '', // string, 必填
fp: '', // string, 必填
};

module.exports = config
module.exports = config;
```

2 需要有node开发环境开发使用 nodejs v12.x, 没有nodejs 官网 下载一个就行. 下载完安装完 node -v 查看版本. 自带包管理器 `npm`
2 需要有 node 开发环境开发使用 nodejs v12.x, 没有 nodejs 官网 下载一个就行. 下载完安装完中终端执行 `node -v` 查看版本. 其自带包管理器 `npm`

3 在目录下执行 `npm install` 或者 `yarn`(不熟悉, 就使用 npm 一样的) 安装依赖, 已经默认配置使用 `taobao` 镜像地址下载依赖包

3 在目录下执行 `npm install` 或者 `yarn`(不熟悉, 就使用 npm 一样的) 安装依赖, 已经默认使用 taobao 镜像地址下载依赖包
4 配置`tasks-pool.js`(以前在*index.js* 中, 现在迁移出来了) 中设置日期`date`和要抢购的 `skuId`, 格式如下

4 index.js 中修改日期和要抢购的skuId
```js
// 年 月 日 时 分 秒 毫秒
// 2020, 0-11, 1-31, 0-24, 0-60 0-60 0-1000
Expand All @@ -55,45 +60,66 @@ const dd3 = new Date(2020, 2, 3, 21, 0, 0, 400).getTime();

// 修改这里, 添加skuId, 和抢购时间 date, 需要更改 月/日 时:分:秒:毫秒
// skuId 获取方法, 打开任意一个商品详情页如 `https://item.jd.com/100011521400.html`, 则 `100011521400` 就是其skuId
const pool = [
export const pool = [
// { skuId: '100011521400', date: dd1 },
{ skuId: '100011551632', date: dd2 },
{ skuId: '100006394713', date: dd2 },
{ skuId: '100011621642', date: dd2 }
// 此示例对应从添加购物车抢购流程, 目前就根据设置了 areaId
// areaId 获取在第5步骤中
{ skuId: '100011621642', date: dd2, areaId: `2_2825_51936` },
];
// 要强制登录
// 因为 x东 24小时就要重新登录, 防止运行时登录状态有效
// 定时抢购时 cookie 过期了就尴尬了
// true 强制扫码不实用cookie, 登录过后频繁重启时记得关闭
// 否则一直要扫码
export const forceLogin = false;
```

5 当前目录下执行 `node index`
5 确定流程是 *预约-购物车-订单详情* 这种,否则忽略这步骤.还要配置地区 `areaId`. 请打开项目目录下 `area/你所在省份`,找到你所在地区 id 复制配置到 `tasks-pool.js` 中。 如 `area/2.上海.txt`, `'崇明县/东平镇:'2_2919_50783',` 对应 `'2_2919_50783'`, 按照上面示范填入`tasks-pool.js`文件中

6 当前目录下执行 `node index`

7 扫描终端中的二维码登录, 24 小时之内重启不需要再次登录, `cookie` 串会保留在本地文件中 `cookie.json` 中。过期的话必须重新扫码

## Todo
- [ ] 针对从购物车提交订单流程。如果此商品已经在购物车中, 则直接抢购不需要执行添加购物车操作了


6 扫描终端中的二维码登录, 24小时之内重启不需要再次登录, cookie 串会保留在本地文件中 `cookie.json`中。过期的话必须重新扫码, 和 jd 官网一致

## Notice

* 目前最好每天上jd, 去找商品, 距离开始前十几分钟启动
* 预约每个人都很容易拿到, 不用使用脚本执行预约, 脚本也有功能, 但是不太需要, 而且没有加入定时
* 这是 node 版本, 不熟悉的可使用 python版本
* https://github.com/zhou-xiaojun/jd_mask
* 功能大同小异, 我根据自身需求加了在终端中扫码, 多进程抢不同商品
* 关于 jd 口罩问题, 发现和地区有很大关系, 有的地区根本不会抢到
* 关于上面的问题, 几个类似库 issues 都有讨论
* https://github.com/zhou-xiaojun/jd_mask/issues/1
* https://github.com/tychxn/jd-assistant/issues/108#issuecomment-592947377
* 发现真的地区差异很大,上海一次没有,朋友江苏连续俩次 ---3-19 日最新更新
* 注意使用最好提前个 `1s`, 因为提交订单前要请求其他俩个接口, 延迟疫苗差不多正好
* 每天最好提前做一次扫码, 在 `//login(true)` 处打开, 会强制扫码登录一遍。或者多提前一会开启脚本
- *购物车提交订单* 流程的话,目前如果预约商品已经在购物车中了, 请先移除!!(目前针对显卡)
-`windows` 系统不友好, 有问题反馈
- 目前最好每天上 jd, 去找商品, 距离开始前十几分钟启动
- 预约每个人都很容易拿到, 不用使用脚本执行预约, 但是不太需要, 而且没有加入定时
- 这是 node 版本, 不熟悉的可使用 python 版本.(本版本借鉴使用了下面部分功能资源)
- https://github.com/zhou-xiaojun/jd_mask
- https://github.com/tychxn/jd-assistant
- 功能大同小异, 我根据自身需求加了在终端中扫码, 多进程抢不同商品
- 关于 jd 口罩问题, 发现和地区有很大关系, 有的地区根本不会抢到(太久了没有在意口罩了把😄)
- 关于上面的问题, 几个类似库 issues 都有讨论
- https://github.com/zhou-xiaojun/jd_mask/issues/1
- https://github.com/tychxn/jd-assistant/issues/108#issuecomment-592947377
- 发现真的地区差异很大,上海一次没有,朋友江苏连续俩次 ---3-19 日最新更新
- 注意使用最好提前个 `1s`, 因为提交订单前要请求其他俩个接口, 延迟疫苗差不多正好
- 每天最好提前做一次扫码,或者多提前一会开启脚本

## 成功案例

* 订单<img src="https://user-images.githubusercontent.com/13815865/77068940-6ee2a180-6a22-11ea-91a9-e174fdd7a96a.png" />
* 订单<img src="https://user-images.githubusercontent.com/13815865/77068877-56728700-6a22-11ea-8102-925cc25a4b92.png" />
- 订单<img src="https://user-images.githubusercontent.com/13815865/77068940-6ee2a180-6a22-11ea-91a9-e174fdd7a96a.png" />
- 订单<img src="https://user-images.githubusercontent.com/13815865/77068877-56728700-6a22-11ea-8102-925cc25a4b92.png" />

更多案例: [issues/2](https://github.com/meooxx/jd_by_mask/issues/2)

## Advanced
## Advanced(废弃)

_解决不了 mac 待机状态, 代码不执行问题后执行很延后_

熟悉 `nodejs``golang` 使用。正常 `master` 版本已经满足实际使用了, 这部分使用说明不会很详细
分支 `feture-golang` 新加了 `golang` 的版本。 跟 `master` 分支上的区别:
`master` 上面全部是 `nodejs`代码,实际使用发现在定时功能和`cookie` 在会话间储存不是很高效。正好略懂 `golang`, 就用 `golang` 把提交订单的部分重写了。
这个分支上面的流程, `nodejs` 负责登录状态维护, 包括登录流程 和 初始 `cookie` 储存。 `golang` 只做定时提交订单这部分流程。下面这段时间,测测实际效果。
完整流程 nodejs 启动, 监听本地 8888 端口在后台。 golang 启动, func init 中访问nodejs https://127.0.0.1:8888/getCookies, 获得一系列cookie等。然后等待预约时间, 提交订单
完整流程 nodejs 启动, 监听本地 8888 端口在后台。 golang 启动, func init 中访问 nodejs https://127.0.0.1:8888/getCookies, 获得一系列 cookie 等。然后等待预约时间, 提交订单

![流程图片](https://github.com/meooxx/jd_by_mask/blob/master/diagram.svg)
173 changes: 173 additions & 0 deletions area/1.北京.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
{
'北京(1)': {
'朝阳区(72)': {
'定福庄(4211)': '1_72_4211',
'三环以内(2799)': '1_72_2799',
'四环到五环之间(2839)': '1_72_2839',
'北苑(4139)': '1_72_4139',
'三环到四环之间(2819)': '1_72_2819',
'管庄(4137)': '1_72_4137',
'五环到六环之间(2840)': '1_72_2840'
},
'丰台区(2805)': {
'六环之外(34545)': '1_2805_34545',
'五环到六环之间(34544)': '1_2805_34544',
'三环到四环之间(2855)': '1_2805_2855',
'四环到五环之间(2832)': '1_2805_2832',
'二环到三环(2854)': '1_2805_2854'
},
'门头沟(2807)': {
'龙泉镇(51553)': '1_2807_51553',
'雁翅镇(51560)': '1_2807_51560',
'永定镇(51554)': '1_2807_51554',
'潭柘寺镇(51556)': '1_2807_51556',
'王平镇(51557)': '1_2807_51557',
'大台镇(51555)': '1_2807_51555',
'斋堂镇(51561)': '1_2807_51561',
'城区(51552)': '1_2807_51552',
'妙峰山镇(51559)': '1_2807_51559',
'军庄镇(51558)': '1_2807_51558',
'清水镇(51562)': '1_2807_51562'
},
'房山区(2808)': {
'长沟镇(51549)': '1_2808_51549',
'城区(51528)': '1_2808_51528',
'周口店镇(51551)': '1_2808_51551',
'蒲洼乡(51539)': '1_2808_51539',
'青龙湖镇(51540)': '1_2808_51540',
'窦店镇(51531)': '1_2808_51531',
'石楼镇(51542)': '1_2808_51542',
'良乡镇(51536)': '1_2808_51536',
'阎村镇(51546)': '1_2808_51546',
'霞云岭乡(51544)': '1_2808_51544',
'大安山乡(51529)': '1_2808_51529',
'十渡镇(51541)': '1_2808_51541',
'燕山地区(51547)': '1_2808_51547',
'琉璃河镇(51537)': '1_2808_51537',
'张坊镇(51548)': '1_2808_51548',
'韩村河镇(51534)': '1_2808_51534',
'长阳镇(51550)': '1_2808_51550',
'南窖乡(51538)': '1_2808_51538',
'佛子庄乡(51532)': '1_2808_51532',
'河北镇(51535)': '1_2808_51535',
'新镇(51545)': '1_2808_51545',
'大石窝镇(51530)': '1_2808_51530',
'史家营乡(51543)': '1_2808_51543'
},
'延庆县(3065)': {
'香营乡(51519)': '1_3065_51519',
'永宁镇(51509)': '1_3065_51509',
'延庆镇(51505)': '1_3065_51505',
'井庄镇(51516)': '1_3065_51516',
'大榆树镇(51515)': '1_3065_51515',
'四海镇(51512)': '1_3065_51512',
'千家店镇(51513)': '1_3065_51513',
'张山营镇(51511)': '1_3065_51511',
'城区(51506)': '1_3065_51506',
'刘斌堡乡(51518)': '1_3065_51518',
'沈家营镇(51514)': '1_3065_51514',
'旧县镇(51510)': '1_3065_51510',
'八达岭镇(51508)': '1_3065_51508',
'大庄科乡(51517)': '1_3065_51517',
'康庄镇(51507)': '1_3065_51507',
'珍珠泉乡(51520)': '1_3065_51520'
},
'昌平区(2901)': {
'城区以外(2906)': '1_2901_2906',
'城区(4136)': '1_2901_4136',
'六环以内(4135)': '1_2901_4135'
},
'通州区(2809)': {
'永顺镇(51218)': '1_2809_51218',
'梨园镇(51219)': '1_2809_51219',
'中仓街道(51228)': '1_2809_51228',
'永乐店镇(51224)': '1_2809_51224',
'玉桥街道(51230)': '1_2809_51230',
'新华街道(51229)': '1_2809_51229',
'宋庄镇(51220)': '1_2809_51220',
'次渠镇(51232)': '1_2809_51232',
'潞城镇(51225)': '1_2809_51225',
'台湖镇(51226)': '1_2809_51226',
'于家务乡(51227)': '1_2809_51227',
'六环内(马驹桥镇)(51216)': '1_2809_51216',
'西集镇(51223)': '1_2809_51223',
'漷县镇(51221)': '1_2809_51221',
'张家湾镇(51222)': '1_2809_51222',
'北苑街道(51231)': '1_2809_51231',
'六环外(马驹桥镇)(51217)': '1_2809_51217'
},
'西城区(2801)': {
'二环到三环(2853)': '1_2801_2853',
'内环到二环里(2827)': '1_2801_2827'
},
'海淀区(2800)': {
'西三旗(4134)': '1_2800_4134',
'四环到五环之间(2850)': '1_2800_2850',
'三环到四环之间(2849)': '1_2800_2849',
'五环到六环之间(2851)': '1_2800_2851',
'六环以外(2852)': '1_2800_2852',
'三环以内(2848)': '1_2800_2848',
'西二旗(4209)': '1_2800_4209'
},
'石景山区(2806)': {
'八大处科技园区(4188)': '1_2806_4188',
'四环到五环内(2831)': '1_2806_2831',
'石景山城区(4187)': '1_2806_4187'
},
'怀柔区(2814)': {
'城区以内(6115)': '1_2814_6115',
'郊区(2847)': '1_2814_2847'
},
'顺义区(2812)': {
'赵全营镇(51149)': '1_2812_51149',
'北务镇(51126)': '1_2812_51126',
'胜利街道(51142)': '1_2812_51142',
'石园街道(51143)': '1_2812_51143',
'高丽营镇(51129)': '1_2812_51129',
'张镇(51148)': '1_2812_51148',
'天竺地区(51145)': '1_2812_51145',
'大孙各庄镇(51128)': '1_2812_51128',
'南彩镇(51138)': '1_2812_51138',
'李遂镇(51134)': '1_2812_51134',
'仁和地区(51141)': '1_2812_51141',
'后沙峪地区(51131)': '1_2812_51131',
'木林镇(51137)': '1_2812_51137',
'空港街道(51132)': '1_2812_51132',
'北小营镇(51127)': '1_2812_51127',
'旺泉街道(51146)': '1_2812_51146',
'北石槽镇(51125)': '1_2812_51125',
'南法信地区(51139)': '1_2812_51139',
'双丰街道(51144)': '1_2812_51144',
'龙湾屯镇(51135)': '1_2812_51135',
'牛栏山地区(51140)': '1_2812_51140',
'杨镇地区(51147)': '1_2812_51147',
'李桥镇(51133)': '1_2812_51133',
'光明街道(51130)': '1_2812_51130',
'马坡地区(51136)': '1_2812_51136'
},
'大兴区(2810)': {
'亦庄经济开发区(51081)': '1_2810_51081',
'五环至六环之间(6501)': '1_2810_6501',
'四环至五环之间(4194)': '1_2810_4194',
'六环以外(4205)': '1_2810_4205'
},
'崇文区(2803)': {
'二环到三环(2842)': '1_2803_2842',
'一环到二环(2829)': '1_2803_2829'
},
'东城区(2802)': {
'内环到三环里(2821)': '1_2802_2821'
},
'宣武区(2804)': {
'内环到三环里(2828)': '1_2804_2828'
},
'平谷区(2953)': {
'城区(6666)': '1_2953_6666',
'城区以外(2954)': '1_2953_2954'
},
'密云区(2816)': {
'城区(6667)': '1_2816_6667',
'城区以外(2862)': '1_2816_2862'
}
}
}
Loading

0 comments on commit 9d19da0

Please sign in to comment.