Skip to content
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

新增查询本地生活服务订单信息 #196

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
690ca22
Update README.md
huaisha1224 Jul 22, 2021
f18804f
Update README.md
huaisha1224 Jul 22, 2021
a81a870
Update README.md
huaisha1224 Jul 22, 2021
78b4e9a
Update README.md
huaisha1224 Jul 22, 2021
3dbe6fb
Update jd_assistant.py
huaisha1224 Jul 22, 2021
2972f1e
Update README.md
huaisha1224 Jul 23, 2021
34dece8
Update README.md
huaisha1224 Jul 23, 2021
aa49ae5
Update jd_assistant.py
huaisha1224 Jul 23, 2021
24f12eb
Merge branch 'master' of https://github.com/huaisha1224/jd-assistant
huaisha1224 Jul 23, 2021
f3cfdb3
new get_order_vercode
huaisha1224 Jul 25, 2021
95ada5e
Update README.md
huaisha1224 Jul 26, 2021
39ed4bb
Update README.md
huaisha1224 Jul 26, 2021
a6f1cde
增加异常错误处理
huaisha1224 Jul 30, 2021
965e6aa
Merge branch 'master' of https://github.com/huaisha1224/jd-assistant
huaisha1224 Jul 30, 2021
57c5318
Update jd_assistant.py
huaisha1224 Aug 3, 2021
c03476e
Update README.md
huaisha1224 Aug 3, 2021
0dbbec0
Update jd_assistant.py
huaisha1224 Aug 5, 2021
d1c10d2
Merge branch 'master' of https://github.com/huaisha1224/jd-assistant
huaisha1224 Aug 5, 2021
edbe55d
Update README.md
huaisha1224 Aug 5, 2021
c4ffe79
Update log.py
huaisha1224 Aug 6, 2021
a8cfa95
增加验证码消费时间输出
huaisha1224 Aug 12, 2021
28fc50f
代码优化
huaisha1224 Aug 14, 2021
1ed89c6
支持提交数据到石墨文档
huaisha1224 Aug 22, 2021
8b73b9a
Update README.md
huaisha1224 Aug 23, 2021
40778b5
Update shimo.py
huaisha1224 Aug 24, 2021
1893796
Merge branch 'master' of https://github.com/huaisha1224/jd-assistant
huaisha1224 Aug 24, 2021
0cb8f8d
1
huaisha1224 Sep 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 15 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# JD-Assistant

[![version](https://img.shields.io/badge/python-3.4+-blue.svg)](https://www.python.org/download/releases/3.4.0/)
[![status](https://img.shields.io/badge/status-stable-green.svg)](https://github.com/tychxn/jd-assistant)
[![status](https://img.shields.io/badge/status-stable-green.svg)](https://github.com/huaisha1224/jd-assistant)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![star, issue](https://img.shields.io/badge/star%2C%20issue-welcome-brightgreen.svg)](https://github.com/tychxn/jd-assistant)
[![star, issue](https://img.shields.io/badge/star%2C%20issue-welcome-brightgreen.svg)](https://github.com/huaisha1224/jd-assistant)

京东抢购助手(短期内不再更新)
京东抢购助手源代码Fork自https://github.com/tychxn/jd-assistant
-由于原作者已不再更新、刚好我又有需要、所以在此基础上进行了修改;

## 主要功能

Expand All @@ -26,6 +27,7 @@
- 有货提交
- 定时提交
- 查询订单 (可选择只显示未付款订单)
- 查询本地生活服务订单中的验证码及其状态(验证码是否已消费)
- 其他
- 商品预约
- 用户信息查询
Expand All @@ -49,43 +51,28 @@ pip install -r requirements.txt

程序主入口在 `main.py`

👉 [使用教程请参看Wiki](https://github.com/tychxn/jd-assistant/wiki/1.-%E4%BA%AC%E4%B8%9C%E6%8A%A2%E8%B4%AD%E5%8A%A9%E6%89%8B%E7%94%A8%E6%B3%95)
👉 [使用教程请参看Wiki](https://github.com/huaisha1224/jd-assistant/wiki/%E4%BA%AC%E4%B8%9C%E6%8A%A2%E8%B4%AD%E5%8A%A9%E6%89%8B)


## 更新记录

- 【2020.03.10】修复了一些小问题。
- 【2020.02.08】修复了查询库存接口响应数据结构变化导致的问题。
- 【2020.02.06】添加下单成功消息推送功能;新增配置参数以减少各种异常情况。
- 【2020.02.03】查询商品库存方法添加超时,避免少数情况下的卡死问题;对部分代码进行了优化。
- 【2020.02.02】重写了监控库存提交订单功能:监控多商品时可以下单任一有库存商品,具体使用方式请参考wiki。
- 【2020.01.29】修复了自定义商品数量时的bug。
- 【2020.01.28】完善了监控库存提交订单功能的代码,具体使用方式请参考wiki。
- 【2020.01.24】修复了查询单个商品库存接口需要添加额外参数的问题。
- 【2020.01.15】提升了部分代码质量。
- 【2019.12.14】解决查询单个商品库存接口变动的问题。
- 【2019.11.10】临时增加预约商品抢购功能。
- 【2019.02.16】更新了普通商品的抢购代码,在Wiki中写了一份使用教程。
- 【2018.11.29】京东更新了抢购商品的下单接口,代码已更新,支持定时抢购。
- 【2018.09.26】京东已下线`字符验证码`接口,`账号密码登录`功能失效,请使用扫码登录`asst.login_by_QRcode()`。
- 【2018.07.28】京东已采用`滑动验证码`替换登录时出现的`字符验证码`,但还没有下线`字符验证码`接口,`账号密码登录`功能依旧可用。等待后续更新滑动验证方式,推荐使用`扫码登录`。
- 【2021.09.06】代码优化
- 【2021.08.23】增加shimo.py模块、支持提交数据到石墨文档
- 【2021.08.12】优化代码、输出增加验证码消费时间
- 【2021.08.05】优化代码、处理某些特殊订单获取不到验证码的情况
- 【2021.08.03】优化代码、处理cookies失败情况下的异常情况
- 【2021.07.22】在原作者代码基础上、增加了查询订单验证码功能

## 备注

- 🌟强烈建议大家在部署代码前使用有货的商品测试下单流程,并且:在京东购物车结算页面设置发票为`电子普通发票-个人`,设置支付方式为`在线支付`,否则可能出现各种未知的下单失败问题。🌟
- 京东商城的登陆/下单机制经常改动,当前测试时间`2020.02.08`。如果失效,欢迎提issue,我会来更新
- 代码在`macOS`中编写,如果在其他平台上运行出行问题,欢迎提issue。
- 京东商城的登陆/下单机制经常改动,原jd-assistant最后一次更新时间时间`2020.03.08`。如果功能失效,欢迎提issue,有时间我会来更新
- 代码在`Win10`中编写,如果在其他平台上运行出行问题,欢迎提issue。

## 待完成的功能

- [ ] Keep session alive
- [✔] 订单验证码查询
- [ ] 抢优惠券

## 不考虑的功能

- ✖️ 支付功能
- ✖️ 多账号抢购

## Sponsor

[![JetBrains](./docs/jetbrains.svg)](https://www.jetbrains.com/?from=jd-assistant)
134 changes: 130 additions & 4 deletions jd_assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from log import logger
from messenger import Messenger
from timer import Timer
import shimo
from util import (
DEFAULT_TIMEOUT,
DEFAULT_USER_AGENT,
Expand Down Expand Up @@ -1011,7 +1012,7 @@ def submit_order_by_time(self, buy_time, retry=4, interval=5):
@check_login
def get_order_info(self, unpaid=True):
"""查询订单信息
:param unpaid: 只显示未付款订单,可选参数,默认为True
:param unpaid: 默认只显示未付款订单,可选参数,默认为True
:return:
"""
url = 'https://order.jd.com/center/list.action'
Expand All @@ -1034,12 +1035,15 @@ def get_order_info(self, unpaid=True):

logger.info('************************订单列表页查询************************')
order_table = soup.find('table', {'class': 'order-tb'})

# 判断一下订单获取是否成功
if order_table == None:
logger.info('订单信息获取失败、请删除cookies文件夹后重新尝试')
table_bodies = order_table.select('tbody')
exist_order = False
for table_body in table_bodies:
# get order status
order_status = get_tag_value(table_body.select('span.order-status')).replace("订单状态:", "")

# check if order is waiting for payment
# wait_payment = bool(table_body.select('a.btn-pay'))
wait_payment = "等待付款" in order_status
Expand All @@ -1050,11 +1054,9 @@ def get_order_info(self, unpaid=True):

exist_order = True

# get order_time, order_id
tr_th = table_body.select('tr.tr-th')[0]
order_time = get_tag_value(tr_th.select('span.dealtime'))
order_id = get_tag_value(tr_th.select('span.number a'))

# get sum_price, pay_method
sum_price = ''
pay_method = ''
Expand Down Expand Up @@ -1084,7 +1086,9 @@ def get_order_info(self, unpaid=True):
if not exist_order:
logger.info('订单查询为空')
except Exception as e:
self.clean_cookies()
logger.error(e)
logger.info('已删除cookies、请重新运行程序')

@deprecated
def _get_seckill_url(self, sku_id):
Expand Down Expand Up @@ -1413,3 +1417,125 @@ def buy_item_in_stock(self, sku_ids, area, wait_all=False, stock_interval=3, sub
return

time.sleep(stock_interval)

@check_login
def get_order_vercode(self, unpaid_new=False):
"""获取已购本地服务订单的验证码已经验证码状态
登录订单中心获取所有订单
通过本地生活服务订单接口查询是否为本地生活服务订单类型
查询验证码、并记录消费状态
:
:vercode_url: 本地生活服务订单接口
"""
url = 'https://order.jd.com/center/list.action'
payload = {
'search': 0,
'd': 1,
's': 4096,
} # Orders for nearly three months
headers = {
'User-Agent': self.user_agent,
'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
}

try:
resp = self.sess.get(url=url, params=payload, headers=headers)
if not response_status(resp):
logger.error('获取订单页信息失败')
return
soup = BeautifulSoup(resp.text, "html.parser")
#print(soup)

#logger.info('************************订单列表页查询************************')
order_table = soup.find('table', {'class': 'order-tb'})
# 判断一下订单获取是否成功
if order_table == None:
logger.info('订单信息获取失败、请删除cookies文件夹后重新尝试')
#print("订单信息获取失败、请删除cookies文件夹后重新尝试")
table_bodies = order_table.select('tbody')
exist_order = False
for table_body in table_bodies:
# get order status
order_status = get_tag_value(table_body.select('span.order-status')).replace("订单状态:", "")
wait_payment = "等待付款" in order_status

# only show unpaid orders if unpaid=True
if unpaid_new and (not wait_payment):
continue
exist_order = True

# 获取订单时间、订单ID
tr_th = table_body.select('tr.tr-th')[0]
order_time = get_tag_value(tr_th.select('span.dealtime'))
order_id = get_tag_value(tr_th.select('span.number a'))
#print("start")
# 本地服务订单接口查询查询消费验证码
vercode_url = "http://locdetails.jd.com/pc/locdetail?orderId={}&modelId=2".format(order_id)
#vercode_url_back = "http://locdetails.jd.com/pc/locdetail?orderId={}&modelId=1".format(order_id)
#vercode_url= "https://locdetails.jd.com/pc/locdetail?orderId=217734548778&modelId=2"
payload = {
'search': 0,
'd': 1,
's': 4096,
} # Orders for nearly three months
headers = {
'User-Agent': self.user_agent,
'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
}

try:
resp = self.sess.get(url=vercode_url, params=payload, headers=headers)
if not response_status(resp):
logger.error('获取订单验证码页信息失败')
return
vercode_soup = BeautifulSoup(resp.text, "html.parser")

order_type = vercode_soup.select('h2') #判断异常

#通过本地服务订单接口查询订单时非本地服务器订单会提示"您的账号与订单信息不匹配或非loc订单,请重新跳转"

if re.search(r'您的账号', str(order_type)): #判断订单是否为本地服务类型订单
order_info_format = '下单时间: {0}---订单号: {1}----{2}'
logger.info(order_info_format.format(order_time, order_id, "非本地生活服务订单"))

#没有关键词说明是本地服务订单类型
else:
order_vercode_str = vercode_soup.select('td.tr-vercode.un-use') #定位验证码位置
order_vercode_status = vercode_soup.select('td.un-use') #消费状态

order_vercode = re.findall(r'\d{12}', str(order_vercode_str))[0] #订单验证码

if re.findall(r'未消费', str(order_vercode_status)): #判断消费状态
vercode_status = re.findall(r'未消费', str(order_vercode_status))[0]
if vercode_status:
submit = shimo.shimo(order_vercode) #调用石墨文档模块提交数据
#print(order_vercode)
order_info_format = '下单时间: {0}---订单号: {1}---验证码: {2} ---消费状态: {3}---提交状态: {4}'
logger.info(order_info_format.format(order_time, order_id, order_vercode, vercode_status, submit))

else:
# 获取验证码消费时间
vercode_usetime = re.findall(r"(\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2} 已消费)", str(vercode_soup))
order_info_format = '下单时间: {0}---订单号: {1}---验证码: {2}----消费状态: {3}'
logger.info(order_info_format.format(order_time, order_id, order_vercode, vercode_usetime[0]))

except Exception as e:
logger.error(e)

if not exist_order:
logger.info('订单查询为空')
except Exception as e:
#print('报错啦')
self.clean_cookies()
logger.error(e)
logger.info('已删除cookies、请重新运行程序')

def clean_cookies(self):
"""清理cookies文件
"""
cookies_path = os.getcwd() + '\cookies'
with os.scandir(cookies_path) as entries:
for entry in entries:
#print(entry.name)
os.remove(cookies_path + '\\' + entry.name)
os.system('pause')
3 changes: 2 additions & 1 deletion log.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
# -*- encoding=utf8 -*-
import logging
import logging.handlers
from time import strftime

LOG_FILENAME = 'jd-assistant.log'
LOG_FILENAME = strftime("jd-assistant_%Y_%m_%d_%H.log")

logger = logging.getLogger()

Expand Down
52 changes: 52 additions & 0 deletions shimo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
提交数据到石墨文档
"""

import requests
import random

def shimo(content):
"""提交数据到石墨文档表单收集器
"""
# 石墨文档提交数据格式
data = {
"duration" : 55, #时间
"formRev" : 1,
"responseContent" : [
{
"guid" : "xxxxx", #石墨文档的guid
"text" : {
"content" : "xxxxxxxx"
},
"type" : 0
}
],
"userFinger" : "-1",
"userName" : "JD"
}

url = "https://shimo.im/api/newforms/forms/xpVxJQJjT3GJ8WhJ/submit"

data['duration'] = random.randint(10,50) #生成随机时间
data['responseContent'][0]['text']['content'] = content
data['userName'] = "JD助手"
# print("Duration: ", data['duration'])
# print("userName: ",data['userName'])
# print("Content: ", data['responseContent'][0]['text']['content'])
# print(data)

response = requests.post(url, json=data) #用post方式提交数据
if response.status_code == 200 or 204:
#print(response.status_code)
return True
else:
return False

if __name__ == '__main__':
vercode = ['7102298241802','1369696304672','5557372871652']
for x in vercode:
shimo(x)
# ok = shimo(x)
# print(ok)