Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
利小寳
jdBuyMask
提交
6fbe67ee
J
jdBuyMask
项目概览
利小寳
/
jdBuyMask
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jdBuyMask
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6fbe67ee
编写于
2月 08, 2020
作者:
C
cycz
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
下单模式
上级
5fe8286e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
212 addition
and
62 deletion
+212
-62
README.md
README.md
+37
-4
configDemo.ini
configDemo.ini
+9
-4
jdBuyMask.py
jdBuyMask.py
+2
-2
jdBuyMask_V2.py
jdBuyMask_V2.py
+158
-46
jdBuyMask_V3.py
jdBuyMask_V3.py
+2
-2
message.py
message.py
+4
-4
未找到文件。
README.md
浏览文件 @
6fbe67ee
...
...
@@ -13,17 +13,48 @@
有人反馈windows有路径问题,把代码都放在一级目录下了。
避免抢购,程序自动一次只买一件
## V2版本
请在configMy.ini 加入商品id、地区id、cookie等参数
区分下单模式(默认2正常模式)
**注意--极速模式默认清空购物车**
正常模式下单流程
-
[x] 检测有货
-
[x] 检测下柜
-
[x] 加入购物车
-
[x] 查看购物车
-
[x] 下单
极速模式下单流程
-
[x] 检测有货
-
[x] 加入购物车
-
[x] 下单
## V3版本(下单更快)
下单更快,但只能扫描单独一件商品
在配置文件configDemo.ini中,填写[V3]下面的skuid
**注意--V3版本默认清空购物车**
V3版本下单流程
-
[x] 提前加入购物车
-
[x] 检测有货
-
[x] 下单
## exe版本,代码版本会更新频繁
感谢
[
Rlacat
](
https://github.com/Rlacat
)
大佬
链接: https://pan.baidu.com/s/1UGODsDR2J1HYtH8m28Bu4Q 提取码: 33te
V2版本 不需要添加url,只需要加入商品id、地区id。刷新更加频繁更快。
(如果想要更疯狂可以调整timesleep参数)
V3版本(下单更快) 只能扫描一件商品,在配置文件configDemo.ini中,填写[V3]下面的skuid
## 温馨提示
-
在京东购物车结算页面设置发票为电子普通发票-个人设置支付方式为在线支付
-
地区id不知道如何获取的,请使用AreaTool.py获取
## 版本
-
[x] python3
## 功能
-
[x] 检查登录
-
[x] 确认是否有货
...
...
@@ -31,6 +62,7 @@ V3
-
[x] 邮件、微信通知
## 更新记录
-
【2020.02.08】V2版本,区分下单模式,config中错别字,bug修复。
-
【2020.02.07】V3版本,减少提交订单的请求量,总而言之就是更快(只能监控一件商品)。
-
【2020.02.07】无货等情况下单失败不重试。
-
【2020.02.07】新增微信通知(http://sc.ftqq.com/3.version 查看sc_key),bug修复。
...
...
@@ -41,4 +73,5 @@ V3
## 反馈问题
-
如果有红包先花掉再开脚本,不然可能需要支付密码
-
出现下单地址不是默认地址的,在线下一单,取getOrderInfo.action链接的cookie
\ No newline at end of file
-
出现下单地址不是默认地址的,在线下一单,取getOrderInfo.action链接的cookie
-
CMD界面卡住、关闭CMD的快速编辑模式就行了
\ No newline at end of file
configDemo.ini
浏览文件 @
6fbe67ee
[config]
# skuids 英文逗号[,]相隔 (分清楚英文和中文逗号)
skuids
=
65466451629,65437208345,7498169,7498165,7263128,7498167,17449572304,37934196731,100001086804,56657322838,56657322841,100005294853,1938795,15595191653,15595191654,45923412989
# 地区id (不知道怎么获取的使用一下AreaTool.py工具)
area
=
19_1607_4773_0
# cookie
cookies_String
=
shshshfpa=21a5db2
# 推送方式 1为邮箱,2为微信
messageT
t
pe
=
1
messageT
y
pe
=
1
# mail
mail
=
xxxxxx@qq.com
# sc_key 方糖微信推送的key 不知道的请看http://sc.ftqq.com/3.version
...
...
@@ -19,10 +18,16 @@ sc_key = test
# 此时下单会要求输入六位数字的支付密码。请在下方配置你的支付密码,如 123456 。
# 如果没有上述情况,下方请留空。
payment_pwd
=
#暂时不填写
eid
=
fp
=
[V2]
# skuids 英文逗号[,]相隔 (分清楚英文和中文逗号) 末尾不要带逗号
skuids
=
65466451629,65437208345,7498169,7498165,7263128,7498167,17449572304,37934196731,100001086804,56657322838,56657322841,100005294853,1938795,15595191653,15595191654,45923412989
# V2版本下单速度区分 极速模式 【1】 和 正常模式 【2】(极速模式缩短不必要的流程)
model
=
2
[V3]
# v3版本的skuid,最多写一件
skuid
=
65466451629
\ No newline at end of file
jdBuyMask.py
浏览文件 @
6fbe67ee
...
...
@@ -19,7 +19,7 @@ import traceback
cookies_String
=
'xxxxxxx'
# 推送方式 1(mail)或 2(wechat)
messageT
t
pe
=
1
messageT
y
pe
=
1
# 有货通知 收件邮箱
mail
=
'xxxxxx@qq.com'
...
...
@@ -49,7 +49,7 @@ eid = ''
fp
=
''
# 支付密码
payment_pwd
=
''
message
=
message
(
messageT
tpe
=
messageTt
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
message
=
message
(
messageT
ype
=
messageTy
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
session
=
requests
.
session
()
session
.
headers
=
{
"User-Agent"
:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36"
,
...
...
jdBuyMask_V2.py
浏览文件 @
6fbe67ee
...
...
@@ -25,18 +25,23 @@ mail = global_config.getRaw('config', 'mail')
# 方糖微信推送的key 不知道的请看http://sc.ftqq.com/3.version
sc_key
=
global_config
.
getRaw
(
'config'
,
'sc_key'
)
# 推送方式 1(mail)或 2(wechat)
messageTtpe
=
global_config
.
getRaw
(
'config'
,
'messageTtpe'
)
messageType
=
global_config
.
getRaw
(
'config'
,
'messageType'
)
# 下单模式
modelType
=
global_config
.
getRaw
(
'V2'
,
'model'
)
# 地区id
area
=
global_config
.
getRaw
(
'config'
,
'area'
)
# 商品id
skuidsString
=
global_config
.
getRaw
(
'
config
'
,
'skuids'
)
skuidsString
=
global_config
.
getRaw
(
'
V2
'
,
'skuids'
)
skuids
=
str
(
skuidsString
).
split
(
','
)
if
not
modelType
:
logger
.
error
(
'请在configDemo.ini文件填写下单model'
)
if
len
(
skuids
[
0
])
==
0
:
logger
.
error
(
'请在config.ini文件中输入你的商品id'
)
logger
.
error
(
'请在config
Demo
.ini文件中输入你的商品id'
)
sys
.
exit
(
1
)
message
=
message
(
messageT
tpe
=
messageTt
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
message
=
message
(
messageT
ype
=
messageTy
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
'''
备用
...
...
@@ -90,10 +95,11 @@ def validate_cookies():
}
resp
=
session
.
get
(
url
=
targetURL
,
params
=
payload
,
allow_redirects
=
False
)
if
resp
.
status_code
==
requests
.
codes
.
OK
:
logger
.
info
(
'
登录成功
'
)
logger
.
info
(
'
校验是否登录[成功]
'
)
return
True
else
:
logger
.
info
(
'第【%s】次请重新获取cookie'
,
flag
)
logger
.
info
(
'校验是否登录[失败]'
)
logger
.
info
(
'请在configDemo.ini文件下更新cookie'
)
time
.
sleep
(
5
)
continue
except
Exception
as
e
:
...
...
@@ -116,7 +122,7 @@ def getUsername():
resultText
=
resultText
.
replace
(
'jQuery339448('
,
''
)
resultText
=
resultText
.
replace
(
')'
,
''
)
usernameJson
=
json
.
loads
(
resultText
)
logger
.
info
(
'登录账号名称
'
+
usernameJson
[
'nick'
])
logger
.
info
(
'登录账号名称
[%s]'
,
usernameJson
[
'nick'
])
'''
...
...
@@ -298,9 +304,7 @@ def get_checkout_page_detail():
return
risk_control
def
submit_order
(
risk_control
,
sku_id
):
def
submit_order
(
risk_control
,
sku_id
):
"""提交订单
重要:
...
...
@@ -376,7 +380,7 @@ def submit_order(risk_control,sku_id):
resultMessage
,
result_code
=
resp_json
.
get
(
'message'
),
resp_json
.
get
(
'resultCode'
)
if
result_code
==
0
:
# self._save_invoice()
if
'验证码不正确'
in
resultMessage
:
if
'验证码不正确'
in
resultMessage
:
resultMessage
=
resultMessage
+
'(验证码错误)'
message
.
send
(
'账号订单提交失败,需要验证码。避免死循环退出程序'
,
False
)
logger
.
info
(
'账号订单提交失败,需要验证码。避免死循环退出程序'
)
...
...
@@ -422,7 +426,7 @@ def item_removed(sku_id):
'''
def
b
uyMask
(
sku_id
):
def
normalModeB
uyMask
(
sku_id
):
cancel_select_all_cart_item
()
cart
=
cart_detail
()
if
sku_id
in
cart
:
...
...
@@ -440,11 +444,19 @@ def buyMask(sku_id):
add_item_to_cart
(
sku_id
)
risk_control
=
get_checkout_page_detail
()
if
len
(
risk_control
)
>
0
:
if
submit_order
(
risk_control
,
sku_id
):
if
submit_order
(
risk_control
,
sku_id
):
return
True
return
False
def
fastModeBuyMask
(
sku_id
):
add_item_to_cart
(
sku_id
)
risk_control
=
get_checkout_page_detail
()
if
len
(
risk_control
)
>
0
:
if
submit_order
(
risk_control
,
sku_id
):
return
True
return
False
'''
查询库存
...
...
@@ -482,44 +494,144 @@ def check_stock():
nohasSkuid
.
append
(
i
)
except
Exception
as
e
:
abnormalSkuid
.
append
(
i
)
logger
.
info
(
'
[%s]个skuid口罩
无货'
,
len
(
nohasSkuid
))
logger
.
info
(
'
检测[%s]个口罩都
无货'
,
len
(
nohasSkuid
))
if
len
(
abnormalSkuid
)
>
0
:
logger
.
info
(
'[%s]类型口罩查询异常'
,
','
.
join
(
abnormalSkuid
))
return
inStockSkuid
flag
=
1
while
(
1
):
try
:
if
flag
==
1
:
validate_cookies
()
getUsername
()
checkSession
=
requests
.
Session
()
checkSession
.
headers
=
{
"User-Agent"
:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36"
,
"Accept"
:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"
,
"Connection"
:
"keep-alive"
}
logger
.
info
(
'第'
+
str
(
flag
)
+
'次 '
)
flag
+=
1
inStockSkuid
=
check_stock
()
for
skuId
in
inStockSkuid
:
'''
删除购物车选中商品
'''
def
remove_item
():
url
=
"https://cart.jd.com/batchRemoveSkusFromCart.action"
data
=
{
't'
:
0
,
'null'
:
''
,
'outSkus'
:
''
,
'random'
:
random
.
random
(),
'locationId'
:
'19-1607-4773-0'
}
headers
=
{
"User-Agent"
:
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.37"
,
"Accept"
:
"application/json, text/javascript, */*; q=0.01"
,
"Referer"
:
"https://cart.jd.com/cart.action"
,
"Host"
:
"cart.jd.com"
,
"Content-Type"
:
"application/x-www-form-urlencoded"
,
"Accept-Encoding"
:
"gzip, deflate, br"
,
"Accept-Encoding"
:
"zh-CN,zh;q=0.9,ja;q=0.8"
,
"Origin"
:
"https://cart.jd.com"
,
"Connection"
:
"keep-alive"
}
resp
=
session
.
post
(
url
,
data
=
data
,
headers
=
headers
)
logger
.
info
(
'清空购物车'
)
if
resp
.
status_code
!=
requests
.
codes
.
OK
:
print
(
'Status: %u, Url: %s'
%
(
resp
.
status_code
,
resp
.
url
))
return
False
return
True
def
select_all_cart_item
():
url
=
"https://cart.jd.com/selectAllItem.action"
data
=
{
't'
:
0
,
'outSkus'
:
''
,
'random'
:
random
.
random
()
}
resp
=
session
.
post
(
url
,
data
=
data
)
if
resp
.
status_code
!=
requests
.
codes
.
OK
:
print
(
'Status: %u, Url: %s'
%
(
resp
.
status_code
,
resp
.
url
))
return
False
return
True
def
normalModeAutoBuy
(
inStockSkuid
):
for
skuId
in
inStockSkuid
:
if
item_removed
(
skuId
):
logger
.
info
(
'[%s]类型口罩有货啦!马上下单'
,
skuId
)
skuidUrl
=
'https://item.jd.com/'
+
skuId
+
'.html'
if
normalModeBuyMask
(
skuId
):
message
.
send
(
skuidUrl
,
True
)
sys
.
exit
(
1
)
else
:
message
.
send
(
skuidUrl
,
False
)
else
:
logger
.
info
(
'[%s]类型口罩有货,但已下柜商品'
,
skuId
)
def
fastModeAutoBuy
(
inStockSkuid
):
for
skuId
in
inStockSkuid
:
logger
.
info
(
'[%s]类型口罩有货啦!马上下单'
,
skuId
)
skuidUrl
=
'https://item.jd.com/'
+
skuId
+
'.html'
if
fastModeBuyMask
(
skuId
):
message
.
send
(
skuidUrl
,
True
)
sys
.
exit
(
1
)
else
:
if
item_removed
(
skuId
):
logger
.
info
(
'[%s]类型口罩有货啦!马上下单'
,
skuId
)
skuidUrl
=
'https://item.jd.com/'
+
skuId
+
'.html'
if
buyMask
(
skuId
):
message
.
send
(
skuidUrl
,
True
)
sys
.
exit
(
1
)
else
:
message
.
send
(
skuidUrl
,
False
)
message
.
send
(
skuidUrl
,
False
)
else
:
logger
.
info
(
'[%s]类型口罩有货,但已下柜商品'
,
skuId
)
timesleep
=
random
.
randint
(
5
,
15
)
/
10
time
.
sleep
(
timesleep
)
if
flag
%
40
==
0
:
logger
.
info
(
'校验是否还在登录'
)
validate_cookies
()
except
Exception
as
e
:
logger
.
info
(
'[%s]商品已下柜,商品列表中踢出'
)
skuids
.
remove
(
skuId
)
select_all_cart_item
()
remove_item
()
def
normalMode
():
flag
=
1
while
(
1
):
try
:
if
flag
==
1
:
validate_cookies
()
getUsername
()
# modelType
logger
.
info
(
'第'
+
str
(
flag
)
+
'次 '
)
flag
+=
1
# 检测库存
inStockSkuid
=
check_stock
()
# 下单任务
normalModeAutoBuy
(
inStockSkuid
)
timesleep
=
random
.
randint
(
5
,
10
)
/
10
time
.
sleep
(
timesleep
)
if
flag
%
40
==
0
:
logger
.
info
(
'校验是否还在登录'
)
validate_cookies
()
except
Exception
as
e
:
print
(
traceback
.
format_exc
())
time
.
sleep
(
10
)
def
fastMode
():
flag
=
1
while
(
1
):
try
:
if
flag
==
1
:
validate_cookies
()
getUsername
()
select_all_cart_item
()
remove_item
()
# modelType
logger
.
info
(
'第'
+
str
(
flag
)
+
'次 '
)
flag
+=
1
# 检测库存
inStockSkuid
=
check_stock
()
# 下单任务
fastModeAutoBuy
(
inStockSkuid
)
timesleep
=
random
.
randint
(
5
,
10
)
/
10
time
.
sleep
(
timesleep
)
if
flag
%
40
==
0
:
logger
.
info
(
'校验是否还在登录'
)
validate_cookies
()
except
Exception
as
e
:
print
(
traceback
.
format_exc
())
time
.
sleep
(
10
)
print
(
traceback
.
format_exc
())
time
.
sleep
(
10
)
if
modelType
==
'2'
:
normalMode
()
elif
modelType
==
'1'
:
fastMode
()
jdBuyMask_V3.py
浏览文件 @
6fbe67ee
...
...
@@ -24,7 +24,7 @@ mail = global_config.getRaw('config', 'mail')
# 方糖微信推送的key 不知道的请看http://sc.ftqq.com/3.version
sc_key
=
global_config
.
getRaw
(
'config'
,
'sc_key'
)
# 推送方式 1(mail)或 2(wechat)
messageT
tpe
=
global_config
.
getRaw
(
'config'
,
'messageTt
pe'
)
messageT
ype
=
global_config
.
getRaw
(
'config'
,
'messageTy
pe'
)
# 地区id
area
=
global_config
.
getRaw
(
'config'
,
'area'
)
# 商品id
...
...
@@ -35,7 +35,7 @@ if len(skuids[0]) == 0:
logger
.
error
(
'请在config.ini文件中输入你的商品id'
)
sys
.
exit
(
1
)
message
=
message
(
messageT
tpe
=
messageTt
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
message
=
message
(
messageT
ype
=
messageTy
pe
,
sc_key
=
sc_key
,
mail
=
mail
)
'''
备用
...
...
message.py
浏览文件 @
6fbe67ee
...
...
@@ -6,16 +6,16 @@ from wechat_ftqq import sendWechat
class
message
(
object
):
"""消息推送类"""
def
__init__
(
self
,
messageT
t
pe
,
sc_key
,
mail
):
if
messageT
t
pe
==
'2'
:
def
__init__
(
self
,
messageT
y
pe
,
sc_key
,
mail
):
if
messageT
y
pe
==
'2'
:
if
not
sc_key
:
raise
Exception
(
'sc_key can not be empty'
)
self
.
sc_key
=
sc_key
elif
messageT
t
pe
==
'1'
:
elif
messageT
y
pe
==
'1'
:
if
not
mail
:
raise
Exception
(
'mail can not be empty'
)
self
.
mail
=
mail
self
.
messageTtpe
=
messageT
t
pe
self
.
messageTtpe
=
messageT
y
pe
def
send
(
self
,
desp
=
''
,
isOrder
=
False
):
desp
=
str
(
desp
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录