代码拉取完成,页面将自动刷新
同步操作将从 zhenghua/jd_seckill 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# -*- coding: utf-8 -*-
"""
JD online shopping helper tool Cart Model
-----------------------------------------------------
only support to login by QR code,
username / password is not working now.
https://baijiahao.baidu.com/s?id=1589809033132183296
https://github.com/Adyzng/jd-autobuy
"""
import bs4
import requests, requests.utils, pickle
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
import os
import time
import json
import random
import datetime
import argparse
#from selenium import webdriver
import importlib,sys
importlib.reload(sys)
#import sys
#reload(sys)
#sys.setdefaultencoding('utf-8')
# get function name
FuncName = lambda n=0: sys._getframe(n + 1).f_code.co_name
def tags_val(tag, key='', index=0):
'''
return html tag list attribute @key @index
if @key is empty, return tag content
'''
if len(tag) == 0 or len(tag) <= index:
return ''
elif key:
txt = tag[index].get(key)
return txt.strip(' \t\r\n') if txt else ''
else:
txt = tag[index].text
return txt.strip(' \t\r\n') if txt else ''
def tag_val(tag, key=''):
'''
return html tag attribute @key
if @key is empty, return tag content
'''
if tag is None:
return ''
elif key:
txt = tag.get(key)
return txt.strip(' \t\r\n') if txt else ''
else:
txt = tag.text
return txt.strip(' \t\r\n') if txt else ''
class JDWrapper(object):
'''
This class used to simulate login JD
'''
def __init__(self, usr_name=None, usr_pwd=None):
# cookie info
self.trackid = ''
self.uuid = ''
self.eid = ''
self.fp = ''
self.usr_name = usr_name
self.usr_pwd = usr_pwd
self.interval = 0
# init url related
self.home = 'https://passport.jd.com/new/login.aspx'
self.login = 'https://passport.jd.com/uc/loginService'
self.imag = 'https://authcode.jd.com/verify/image'
self.auth = 'https://passport.jd.com/uc/showAuthCode'
self.stop = False
self.sess = requests.Session()
self.headers = {
#'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0',
'ContentType': 'text/html; charset=utf-8',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,zh;q=0.8',
'Connection' : 'keep-alive',
}
self.cookies = {
}
'''
try:
self.browser = webdriver.PhantomJS('phantomjs.exe')
except Exception as e:
print 'Phantomjs initialize failed :', e
exit(1)
'''
@staticmethod
def print_json(resp_text):
'''
format the response content
'''
if resp_text[0] == '(':
resp_text = resp_text[1:-1]
for k,v in json.loads(resp_text).items():
print (u'%s : %s' % (k, v))
@staticmethod
def response_status(resp):
if resp.status_code != requests.codes.OK:
print ('Status: %u, Url: %s' % (resp.status_code, resp.url))
return False
return True
def _need_auth_code(self, usr_name):
# check if need auth code
#
auth_dat = {
'loginName': usr_name,
}
payload = {
'r' : random.random(),
'version' : 2015
}
resp = self.sess.post(self.auth, data=auth_dat, params=payload)
if self.response_status(resp) :
js = json.loads(resp.text[1:-1])
return js['verifycode']
print (u'获取是否需要验证码失败')
return False
def _get_auth_code(self, uuid):
# image save path
image_file = os.path.join(os.getcwd(), 'authcode.jfif')
payload = {
'a' : 1,
'acid' : uuid,
'uid' : uuid,
'yys' : str(int(time.time() * 1000)),
}
# get auth code
r = self.sess.get(self.imag, params=payload)
if not self.response_status(r):
print (u'获取验证码失败')
return False
with open (image_file, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
f.write(chunk)
f.close()
os.system('start ' + image_file)
return str(raw_input('Auth Code: '))
def _login_once(self, login_data):
# url parameter
payload = {
'r': random.random(),
'uuid' : login_data['uuid'],
'version' : 2015,
}
resp = self.sess.post(self.login, data=login_data, params=payload)
if self.response_status(resp):
js = json.loads(resp.text[1:-1])
#self.print_json(resp.text)
if not js.get('success') :
print (js.get('emptyAuthcode'))
return False
else:
return True
return False
def _login_try(self):
""" login by username and password, but not working now.
.. deprecated::
Use `login_by_QR`
"""
# get login page
#resp = self.sess.get(self.home)
print ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print (u'{0} > 登陆'.format(datetime.datetime.now()))
try:
# 2016/09/17 PhantomJS can't login anymore
self.browser.get(self.home)
soup = bs4.BeautifulSoup(self.browser.page_source, "html.parser")
# set cookies from PhantomJS
for cookie in self.browser.get_cookies():
self.sess.cookies[cookie['name']] = str(cookie['value'])
#for (k, v) in self.sess.cookies.items():
# print '%s: %s' % (k, v)
# response data hidden input == 9 ??. Changed
inputs = soup.select('form#formlogin input[type=hidden]')
rand_name = inputs[-1]['name']
rand_data = inputs[-1]['value']
token = ''
for idx in range(len(inputs) - 1):
id = inputs[idx]['id']
va = inputs[idx]['value']
if id == 'token':
token = va
elif id == 'uuid':
self.uuid = va
elif id == 'eid':
self.eid = va
elif id == 'sessionId':
self.fp = va
auth_code = ''
if self.need_auth_code(self.usr_name):
auth_code = self.get_auth_code(self.uuid)
else:
print (u'无验证码登陆')
login_data = {
'_t': token,
'authcode': auth_code,
'chkRememberMe': 'on',
'loginType': 'f',
'uuid': self.uuid,
'eid': self.eid,
'fp': self.fp,
'nloginpwd': self.usr_pwd,
'loginname': self.usr_name,
'loginpwd': self.usr_pwd,
rand_name : rand_data,
}
login_succeed = self.login_once(login_data)
if login_succeed:
self.trackid = self.sess.cookies['TrackID']
print (u'登陆成功 %s' % self.usr_name)
else:
print (u'登陆失败 %s' % self.usr_name)
return login_succeed
except Exception as e:
print ('Exception:', e.message)
raise
finally:
self.browser.quit()
return False
def checkLoginQR(self):
return False
checkUrl = 'https://passport.jd.com/uc/qrCodeTicketValidation'
try:
print ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print (u'{0} > 自动登录中... '.format(datetime.datetime.now()))
with open('jd_cookie', 'rb') as f:
cookies = requests.utils.cookiejar_from_dict(pickle.load(f))
resp = requests.get(checkUrl, cookies=cookies)
if resp.status_code != requests.codes.OK:
print (u'登录过期, 请重新登录!')
return False
else:
print(u'登录成功。')
return True
return False
except Exception as e:
print(u'cookie不存在!')
return False
else:
pass
finally:
pass
return False
def checkLogin(self):
checkUrl = 'https://passport.jd.com/loginservice.aspx'
try:
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print(u'{0} > 自动登录中... '.format(datetime.datetime.now()))
self.cookies = requests.utils.cookiejar_from_dict(self.get_cookie("cookie_jd.txt"))
self.headers['Host'] = 'passport.jd.com'
self.headers['Referer'] = 'https://passport.jd.com/new/login.aspx'
resp = self.sess.get(checkUrl,
headers = self.headers,
cookies = self.cookies,
params = {'method':'Login',
'callback':'jQuery%u' % random.randint(100000, 999999),
'_': (int)(time.time() * 1000)}
) # cookie登录
if resp.status_code != requests.codes.OK:
print(u'登录失败,cookie过期, 请重新登录!')
return False
else:
n1 = resp.text.find('(')
n2 = resp.text.find(')')
rs = json.loads(resp.text[n1 + 1:n2])
if rs['Identity']['Unick'] == '' or rs['Identity']['IsAuthenticated'] == True:
print(u'{} : {} {}'.format(rs['Identity']['Unick'], rs['Identity']['Name'],'登录成功。'))
return True
else:
print(u'登录失败,cookie过期, 请重新登录!')
time.sleep(3)
return False
return False
except Exception as e:
print(u'cookie不存在!')
return False
else:
pass
finally:
pass
return False
def login_by_QR(self):
# jd login by QR code
try:
print ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print (u'{0} > 请打开京东手机客户端,准备扫码登陆:'.format(datetime.datetime.now()))
urls = (
'https://passport.jd.com/new/login.aspx',
'https://qr.m.jd.com/show',
'https://qr.m.jd.com/check',
'https://passport.jd.com/uc/qrCodeTicketValidation'
)
# step 1: open login page
resp = self.sess.get(
urls[0],
headers = self.headers
)
if resp.status_code != requests.codes.OK:
print (u'获取登录页失败: %u' % resp.status_code)
return False
## save cookies
for k, v in resp.cookies.items():
self.cookies[k] = v
# step 2: get QR image
resp = self.sess.get(
urls[1],
headers = self.headers,
cookies = self.cookies,
params = {
'appid': 133,
'size': 147,
't': (int)(time.time() * 1000)
}
)
if resp.status_code != requests.codes.OK:
print (u'获取二维码失败: %u' % resp.status_code)
return False
## save cookies
for k, v in resp.cookies.items():
self.cookies[k] = v
## save QR code as png
image_file = 'qr.png'
with open (image_file, 'wb') as f:
for chunk in resp.iter_content(chunk_size=1024):
f.write(chunk)
## show QR code image and scan it with JD App
if os.name == "nt":
# for windows
os.system('start ' + image_file)
else:
if os.uname()[0] == "Linux":
# for linux platform
os.system("eog " + image_file)
else:
# for Mac platform
os.system("open " + image_file)
# step 3: check scan result
## mush have
# check if QR code is scanned and ervery 3 sconds
self.headers['Host'] = 'qr.m.jd.com'
self.headers['Referer'] = 'https://passport.jd.com/new/login.aspx'
qr_ticket = None
retry_times = 100
while retry_times:
retry_times -= 1
resp = self.sess.get(
urls[2],
headers = self.headers,
cookies = self.cookies,
params = {
'callback': 'jQuery%u' % random.randint(100000, 999999),
'appid': 133,
'token': self.cookies['wlfstk_smdl'],
'_': (int)(time.time() * 1000)
}
)
if resp.status_code != requests.codes.OK:
continue
'''
jQuery8852867({
"code" : 201,
"msg" : "二维码未扫描 ,请扫描二维码"
})
jQuery1234567({
"code" : 202,
"msg" : "请手机客户端确认登录"
})
'''
n1 = resp.text.find('(')
n2 = resp.text.find(')')
rs = json.loads(resp.text[n1+1:n2])
if rs['code'] == 200:
print (u'{} : {}'.format(rs['code'], rs['ticket']))
qr_ticket = rs['ticket']
break
else:
print (u'{} : {}'.format(rs['code'], rs['msg']))
time.sleep(3)
if not qr_ticket:
print (u'二维码登陆失败')
return False
# step 4: validate scan result
## must have
self.headers['Host'] = 'passport.jd.com'
self.headers['Referer'] = 'https://passport.jd.com/uc/login?ltype=logout'
resp = self.sess.get(
urls[3],
headers = self.headers,
cookies = self.cookies,
params = {'t' : qr_ticket },
)
if resp.status_code != requests.codes.OK:
print (u'二维码登陆校验失败: %u' % resp.status_code)
return False
## 京东有时候会认为当前登录有危险,需要手动验证
## url: https://safe.jd.com/dangerousVerify/index.action?username=...
res = json.loads(resp.text)
if not resp.headers.get('P3P'):
if res.has_key('url'):
print (u'需要手动安全验证: {0}'.format(res['url']))
return False
else:
self.print_json(res)
print (u'登陆失败!!')
return False
## login succeed
self.headers['P3P'] = resp.headers.get('P3P')
for k, v in resp.cookies.items():
self.cookies[k] = v
with open('jd_cookie', 'wb') as f:
#pickle.dump(self.cookies, f)
pickle.dump(self.sess.cookies, f)
print (u'登陆成功')
return True
except Exception as e:
print ('Exp:', e)
raise
return False
def good_stock(self, stock_id, good_count=1, area_id=None):
'''
33 : on sale,
34 : out of stock
36 : presell
'''
# http://ss.jd.com/ss/areaStockState/mget?app=cart_pc&ch=1&skuNum=3180350,1&area=1,72,2799,0
# response: {"3180350":{"a":"34","b":"1","c":"-1"}}
#stock_url = 'http://ss.jd.com/ss/areaStockState/mget'
# http://c0.3.cn/stocks?callback=jQuery2289454&type=getstocks&skuIds=3133811&area=1_72_2799_0&_=1490694504044
# jQuery2289454({"3133811":{"StockState":33,"freshEdi":null,"skuState":1,"PopType":0,"sidDely":"40","channel":1,"StockStateName":"现货","rid":null,"rfg":0,"ArrivalDate":"","IsPurchase":true,"rn":-1}})
# jsonp or json both work
stock_url = 'https://c0.3.cn/stocks'
payload = {
'type' : 'getstocks',
'skuIds' : str(stock_id),
'area' : area_id or '1_72_2799_0', # area change as needed
}
try:
# get stock state
resp = self.sess.get(stock_url, params=payload)
if not self.response_status(resp):
print (u'获取商品库存失败')
return (0, '')
# return json
resp.encoding = 'gbk'
stock_info = json.loads(resp.text)
stock_stat = int(stock_info[stock_id]['StockState'])
stock_stat_name = stock_info[stock_id]['StockStateName']
#stock_Ext = stock_info[stock_id]['Ext']
# 33 : on sale, 34 : out of stock, 36: presell
return stock_stat, stock_stat_name
except Exception as e:
print ('Stocks Exception:', e)
time.sleep(5)
return (0, '')
def good_stockone(self, stock_id, area_id=None):
# 当前只对商品3749111有效
# jsonp or json both work
stock_url = 'https://c0.3.cn/stock'
payload = {
'skuId': str(stock_id),
'area': area_id or '13_1007_3521_3519', # area change as needed
'venderId':'1000001462', #供货商 shopid
'cat': '9192,9196,1502', #首页 > 医药保健 > 计生情趣 > 避孕套
'buyNum': 1,
'choseSuitSkuIds': '',
'extraParam': '{"originid":"1"}',
'ch': '1',
'fqsp': '0',
'pduid': '1516159981380471329757',#
'pdpin': '',
'detailedAdd': 'null',
'callback': 'jQuery%u' % random.randint(100000, 999999),
}
try:
# get stock state
self.headers['Host'] = 'c0.3.cn'
self.headers['Referer'] = 'https://item.jd.com/'+str(stock_id)+'.html'
resp = self.sess.get(stock_url,
headers=self.headers,
params=payload,
cookies = {
'c3cn': 'Ef9Ms03P'
})
if not self.response_status(resp):
print(u'获取商品库存失败')
return (0, '')
n1 = resp.text.find('(')
n2 = resp.text.find(')')
rs = json.loads(resp.text[n1 + 1:n2])
Ext = rs['stock']['Ext']
return Ext
except Exception as e:
print('Stocks Exception:', e)
return (0, '')
def good_price(self, stock_id):
# get good price
url = 'http://p.3.cn/prices/mgets'
payload = {
'type' : 1,
'pduid' : int(time.time() * 1000),
'skuIds' : 'J_' + stock_id,
}
price = '?'
try:
resp = self.sess.get(url, params=payload)
resp_txt = resp.text.strip()
#print resp_txt
js = json.loads(resp_txt[1:-1])
#print u'价格', 'P: {0}, M: {1}'.format(js['p'], js['m'])
price = js.get('p')
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
return price
def good_detail(self, stock_id, area_id=None):
# return good detail
good_data = {
'id': stock_id,
'name': '',
'link': '',
'price': '',
'stock': '',
'stockName': '',
'stock_Ext': '',
}
try:
# shop page
item_link = 'http://item.jd.com/{0}.html'.format(stock_id)
resp = self.sess.get(item_link)
# good page
soup = bs4.BeautifulSoup(resp.text, "html.parser")
# good name
tags = soup.select('div#name h1')
if len(tags) == 0:
tags = soup.select('div.sku-name')
good_data['name'] = tags_val(tags).strip(' \t\r\n')
tagsqiang = soup.select('a#choose-btn-ko')
print(tagsqiang)
linkqiang = tags_val(tagsqiang, key='href')
if linkqiang[:2] == '//': linkqiang = 'https:' + linkqiang
resp2 = self.sess.get(linkqiang, cookies=self.cookies)
soup2 = bs4.BeautifulSoup(resp2.text, "html.parser")
# cart link
tags = soup.select('a#InitCartUrl')
link = tags_val(tags, key='href')
if link[:2] == '//': link = 'http:' + link
good_data['link'] = link
except Exception as e:
print('Exp {0} : {1}'.format(FuncName(), e))
# good price
good_data['price'] = self.good_price(stock_id)
# good stock
good_data['stock'], good_data['stockName'] = self.good_stock(stock_id=stock_id,
area_id=area_id)
# '有货'33 else '无货'
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print(u'{0} > 商品详情和库存'.format(datetime.datetime.now()))
print(u'编号:{0}'.format(good_data['id']))
print(u'库存:{0}{1}'.format(good_data['stockName'], good_data['stock']))
print(u'价格:{0}'.format(good_data['price']))
print(u'名称:{0}'.format(good_data['name']))
if good_data['link'] == '':
good_data['link'] = u'https://cart.jd.com/gate.action?pid={0}&pcount=1&ptype=1'.format(good_data['id'])
print(u'链接:{0}'.format(good_data['link']))
return good_data
# 将cookie转为字典
def get_cookie(self,cookiefile):
with open(cookiefile) as f:
cookies = {}
for line in f.read().split(';'):
name, value = line.strip().split('=', 1)
cookies[name] = value
return cookies
def good_yuyue(self,stock_id):
try:
url = 'https://yushou.jd.com/youshouinfo.action'
resp = self.sess.get(
url,
params={'sku':stock_id},
)
rs = json.loads(resp.text)
if 'url' in rs: #Python3以后删除了has_key()方法!if 'key' in dict
url = rs['url'] ##//yushou.jd.com/toYuyue.action?sku=4007899&key=7ea883c45aa4a52d2d9879cc1042b1dd
if url[:2] == '//': url = 'https:' + url
else:
return '0','非预售商品' #非预售商品
self.headers['Referer'] = 'https://item.jd.com/' + stock_id + '.html'
self.headers['Host'] = 'yushou.jd.com'
self.headers['Upgrade-Insecure-Requests'] = '1'
resp = self.sess.get(
url,
headers=self.headers,
# allow_redirects=False,
)
#print(resp.text)
return '1', 'yushou' #'预约成功,已获得抢购资格' 或者 '您已成功预约过了,无需重复预约'
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
return '0', '预约发生错误'
'''
<div class="bd-right">
<p class="bd-right-result">
<i></i>
预约成功,已获得抢购资格
</p>
<p class="bd-right-time">商品将于<span class="time-details">2018-03-15 00:00:00</span>准时开售</p>
</h3>
<p class="bd-right-intro">温馨提示:可以在 我的京东-我的活动-我的预约 中查看已预约商品商品开售后点击“立即抢购”</p>
<p class="bd-right-mybooking">
<a clstag="pageclick|keycount|201602011|8" href="//yushou.jd.com/member/qualificationList.action" class="btn-a mybooking-a">查看我的预约</a>
<a clstag="pageclick|keycount|201602011|9" href="#none" class="booking-share share-btn" onclick="shareYushou()"><i></i>分享</a>
</p>
</div>
'''
def good_qiang1(self, stock_id):
modelname = '抢购模式'
print(self.cookies)
self.cookies = requests.utils.cookiejar_from_dict(self.get_cookie("cookie_jd.txt")) #
print(self.cookies)
self.headers['Referer'] = 'https://item.jd.com/' + stock_id + '.html'
self.headers['Host'] = 'itemko.jd.com'
self.headers['Upgrade-Insecure-Requests'] = '1'
self.headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
#get sn
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
while now < options.stime:
time.sleep(0.05)
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
url='https://itemko.jd.com/itemShowBtn'
# https://itemko.jd.com/itemShowBtn?callback=jQuery6315326&skuId=4007899&from=pc&_=1520923884474
print(u'{0} > {1} 获取sn开始{2}'.format(datetime.datetime.now(), modelname, url))
params = {
'callback': 'jQuery%u' % random.randint(100000, 999999),
'skuId': stock_id,
'from':'pc',
'_': (int)(time.time() * 1000)
}
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
params=params,
allow_redirects=False,
)
n1 = resp.text.find('(')
n2 = resp.text.find(')')
rs = json.loads(resp.text[n1 + 1:n2])
snUrl = rs['url']
n1 = snUrl.find('sn=')
n2 = snUrl.find('from=')
sn = snUrl[n1 + 3:n2 - 1]
print(u'{0} > {1} 获取sn结束{2}'.format(datetime.datetime.now(), modelname, sn))
if sn == '':
return False
try:
url = 'https://divide.jd.com/user_routing'
print(u'{0} > {1} 开始访问第一个地址{2}'.format(datetime.datetime.now(), modelname, url))
self.headers['Host'] = 'divide.jd.com'
payload = {
'from': 'pc',
'skuId': stock_id,
'sn': sn,
}
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
params=payload,
allow_redirects=False,
)
print(u'{0} > {1} 结束访问第一个地址{2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code == 302:
url = resp.headers.get('Location') # https://marathon.jd.com/captcha.html?from=pc&skuId=6359118&sn=534c9e9a742455e6340f522584bb0be8
print(u'{0} > {1} 开始访问第二个地址{2}'.format(datetime.datetime.now(), modelname, url))
self.headers['Host'] = 'marathon.jd.com'
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
allow_redirects=False,
)
print(u'{0} > {1} 结束访问第二个地址{2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code == 302:
url = resp.headers.get('Location') #https://marathon.jd.com/seckill/seckill.action?skuId=6359118&num=1&rid=1520903766
print(u'{0} > {1} 开始访问第三个地址 生成订单 {2}'.format(datetime.datetime.now(), modelname, url))
if url=='https://marathon.jd.com/koFail.html':
return False
self.headers['Host'] = 'marathon.jd.com'
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
allow_redirects=False,
)
print(u'{0} > {1} 结束访问第三个地址 生成订单 {2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code == 302:
url = resp.headers.get("Location")
if url == 'https://marathon.jd.com/koFail.html':
print("下单失败",url)
return False
elif resp.status_code != requests.codes.OK:
return False
else:
# https://marathon.jd.com/seckill/submitOrder.action?skuId=4007899&vid=
order_url = 'https://marathon.jd.com/seckill/submitOrder.action'
self.headers['Host'] = 'marathon.jd.com'
orderpara = {
}
print(u'{0} > {1} 超级秒杀。开始提交订单'.format(datetime.datetime.now(), modelname))
rp = self.sess.post(order_url, params=orderpara, cookies=self.cookies)
if rp.status_code == 200:
print(u'超级秒杀。请求成功。StatusCode:', rp.status_code)
print(rp.text)
js = json.loads(rp.text)
if js['success'] == True:
print(u'请前往东京官方商城付款')
print(u'下单成功!订单号:{0}'.format(js['orderId']))
return True
else:
print(u'下单失败!<{0}: {1}>'.format(js['resultCode'], js['message']))
if str(js['message']).find('活动已经结束了') > 0:
# <61040: 啊哦,活动已经结束了,没有抢到商品东田(DONGTIAN)洗护套组(增量蓬松洗发水220ml+增量蓬松护发素220ml+头皮舒缓精华液30ml)!别灰心,请再逛逛其他商品吧!>
self.stop = True
return False
if str(js['message']).find('正在参与抢购活动,请重新') > 0:
# <600126: 抱歉,惠氏(Wyeth)S-26铂臻学儿乐奶粉4段 瑞士进口 3-7岁幼儿配方 800克(罐装) 新包装正在参与抢购活动,请重新回到商品详情页,使用“立即抢购”进行购买>
self.stop = True
return False
if js['resultCode'] == '60017':
# 60017: 您多次提交过快,请稍后再试
time.sleep(1)
# if js['resultCode'] == '0':
# print('悲剧了,需要验证码') #<0: 验证码不正确,请重新填写>
else:
print(u'超级秒杀。请求失败。StatusCode:', rp.status_code)
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
#Exp good_qiang : Exceeded 30 redirects.
return False
def good_qiang2(self, stock_id):
modelname = '加车模式'
print(self.cookies)
self.cookies = requests.utils.cookiejar_from_dict(self.get_cookie("cookie_jd.txt"))
print(self.cookies)
# get key
print(u'{0} > {1} 获取key开始{2}'.format(datetime.datetime.now(), modelname, ""))
#https://yushou.jd.com/youshouinfo.action?callback=fetchJSON&sku=1160762479
url = 'https://yushou.jd.com/youshouinfo.action?callback=fetchJSON&sku='+stock_id
self.headers['Referer'] = 'https://item.jd.com/' + stock_id + '.html'
self.headers['Host'] = 'yushou.jd.com'
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
)
n1 = resp.text.find('(')
n2 = resp.text.find(')')
rs = json.loads(resp.text[n1 + 1:n2])
keyUrl = rs['url']
#"//yushou.jd.com/toYuyue.action?sku=4007899&key=7ea883c45aa4a52d2d9879cc1042b1dd"
#"//yushou.jd.com/qianggou.action?sku=4007899&key=7ea883c45aa4a52d2d9879cc1042b1dd"
n1 = keyUrl.find('key=')
key = keyUrl[n1 + 4:]
print(u'{0} > {1} 获取key结束{2}'.format(datetime.datetime.now(), modelname, key))
if key == '':
return False
try:
#//yushou.jd.com/qianggou.action?sku=1160762479&key=96ddb7c72dc344f138ca692e470b5b2d
url = 'http://yushou.jd.com/qianggou.action'
self.headers['Host'] = 'yushou.jd.com'
self.headers['Upgrade-Insecure-Requests'] = '1'
self.headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
print(u'{0} > 开始访问第一个地址 {1} {2}'.format(datetime.datetime.now(), modelname, url))
payload = {
'sku': stock_id,
'key': key,
}
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
params=payload,
allow_redirects=False,
)
print(u'{0} > 结束访问第一个地址 {1} {2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code == 302:
url = resp.headers.get('Location') # http://cart.jd.com/cart/dynamic/gate.action?pid=1160762479&pcount=1&ptype=1
if url.find("passport.jd.com") >= 0:
print("请重新登录?")
print(u'{0} > 跳转地址是 {1} {2}'.format(datetime.datetime.now(), modelname, url))
return False
self.headers['Host'] = 'cart.jd.com'
print(u'{0} > 开始访问第二个地址 {1} {2}'.format(datetime.datetime.now(), modelname, url))
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
allow_redirects=False,
)
print(u'{0} > 结束访问第二个地址{1}{2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code == 302:
#
if not resp.headers.get('P3P'):
return False # 需要手动安全验证 登陆失败
#self.headers['P3P'] = resp.headers.get('P3P')
# set cookie
for k, v in resp.cookies.items():
self.cookies[k] = v
url = resp.headers.get('Location') #https://cart.jd.com/addToCart.html?rcd=1&pid=1160762479&pc=1&eb=1&rid=1521160729864&em=
print(u'{0} > 开始访问第三个地址{1}{2}'.format(datetime.datetime.now(), modelname, url)) #---------------------------------------添加购物车
if url=='https://marathon.jd.com/koFail.html': #添加购物车失败
return False
resp = self.sess.get(
url,
headers=self.headers,
cookies=self.cookies,
)
print(u'{0} > 结束访问第三个地址{1}{2}'.format(datetime.datetime.now(), modelname, url))
if resp.status_code != requests.codes.OK:
return False
else:
soup = bs4.BeautifulSoup(resp.text, "html.parser")
# tag if add to cart succeed
tag = soup.select('h3.ftx-02')
if tag is None:
tag = soup.select('div.p-name a')
if tag is None or len(tag) == 0:
print(u'添加到购物车失败')
return False
if str(tags_val(tag)).find("成功加入购物车") >= 0: #商品已成功加入购物车!
# cart link
tags = soup.select('a#GotoShoppingCart') #https://cart.jd.com/cart.action?r=0.18686528456229334
link = tags_val(tags, key='href')
if link[:2] == '//': link = 'https:' + link
self.headers['Referer'] = url
resp2 = self.sess.get(link, headers=self.headers, cookies=self.cookies) #---------------------------------------打开购物车
# set cookie
for k, v in resp2.cookies.items():
self.cookies[k] = v
#去结算---------------------------------------------------------------------------------------------------------去结算
#https://trade.jd.com/shopping/order/getOrderInfo.action?rid=1521164554267
self.order_info(options.submit)
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
#Exp good_qiang : Exceeded 30 redirects.
return False
def add_cart(self,options,link):
print('add cart and change count ', datetime.datetime.now())
# change buy count
# //cart.jd.com/gate.action?pid=497502&pcount=1&ptype=1
if options.count != 1:
link = link.replace('pcount=1', 'pcount={0}'.format(options.count))
# add to cart
resp = self.sess.get(link, cookies=self.cookies)
soup = bs4.BeautifulSoup(resp.text, "html.parser")
# tag if add to cart succeed
tag = soup.select('h3.ftx-02')
if tag is None:
tag = soup.select('div.p-name a')
if tag is None or len(tag) == 0:
print(u'添加到购物车失败')
return False
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print(u'{0} > 添加到购物详情'.format(datetime.datetime.now()))
print(u'链接:{0}'.format(link))
print(u'结果:{0}'.format(tags_val(tag)))
# change count after add to shopping cart
# self.buy_good_count(options.good, options.count)
def buy(self, options):
print('buy beginning',datetime.datetime.now())
# stock detail
good_data = self.good_detail(options.good)
print('show good detail',datetime.datetime.now())
'''
# retry until stock not empty
if good_data['stock'] != 33:
# flush stock state
while good_data['stock'] != 33 and options.flush:
print(u'%s <%s> <%s>' % (datetime.datetime.now(), good_data['stockName'], good_data['name']))
time.sleep(options.wait / 1000.0)
good_data['stock'], good_data['stockName'] = self.good_stock(stock_id=options.good,
area_id=options.area)
# retry detail
# good_data = self.good_detail(options.good)
'''
try:
#self.add_cart(options, good_data['link'])
print("NOT NEED ADD CART")
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
else:
self.cart_detail()
return self.order_info(options.submit)
return False
def buy_good_count(self, good_id, count):
url = 'http://cart.jd.com/changeNum.action'
payload = {
'venderId': '8888',
'pid': good_id,
'pcount': count,
'ptype': '1',
'targetId': '0',
'promoID':'0',
'outSkus': '',
'random': random.random(),
'locationId':'1-72-2799-0', # need changed to your area location id
}
try:
rs = self.sess.post(url, params = payload, cookies = self.cookies)
if rs.status_code == 200:
js = json.loads(rs.text)
if js.get('pcount'):
print (u'数量:%s @ %s' % (js['pcount'], js['pid']))
return True
else:
print (u'购买 %d 失败' % count)
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
return False
def cart_detail(self):
print('show cart detail', datetime.datetime.now())
# list all goods detail in cart
cart_url = 'https://cart.jd.com/cart.action'
cart_header = u'购买 数量 单价 小计 商品'
cart_format = u'{0:8}{1:8}{2:12}{3:12}{4}'
try:
resp = self.sess.get(cart_url, cookies = self.cookies)
resp.encoding = 'utf-8'
soup = bs4.BeautifulSoup(resp.text, "html.parser")
print ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print (u'{0} > 购物车明细'.format(datetime.datetime.now()))
print (cart_header)
for item in soup.select('div.item-form'):
check = tags_val(item.select('div.cart-checkbox input'), key='checked')
check = ' + ' if check else ' - '
count = tags_val(item.select('div.quantity-form input'), key='value')
price = tags_val(item.select('div.p-price strong'))
sums = tags_val(item.select('div.p-sum strong'))
gname = tags_val(item.select('div.p-name a'))
#: ¥字符解析出错, 输出忽略¥
print (cart_format.format(check, count, price[1:], sums[1:], gname))
t_count = tags_val(soup.select('div.amount-sum em'))
t_value = tags_val(soup.select('span.sumPrice em'))
print (u'总数: {0}'.format(t_count))
print (u'总额: {0}'.format(t_value[1:]))
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
def order_info(self, submit=False):
# get order info detail, and submit order
print ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print (u'{0} > 订单详情'.format(datetime.datetime.now()))
try:
order_url = 'http://trade.jd.com/shopping/order/getOrderInfo.action'
payload = {
'rid' : str(int(time.time() * 1000)),
}
# get preorder page
rs = self.sess.get(order_url, params=payload, cookies = self.cookies)
soup = bs4.BeautifulSoup(rs.text, "html.parser")
# order summary
payment = tag_val(soup.find(id='sumPayPriceId'))
detail = soup.find(class_='fc-consignee-info')
if detail:
snd_usr = tag_val(detail.find(id='sendMobile'))
snd_add = tag_val(detail.find(id='sendAddr'))
print (u'应付款:{0}'.format(payment))
print (snd_usr)
print (snd_add)
# just test, not real order
if not submit:
print('not submit stopped', datetime.datetime.now())
return False
# order info
payload = {
'overseaPurchaseCookies': '',
'submitOrderParam.btSupport': '1',
'submitOrderParam.ignorePriceChange': '0',
'submitOrderParam.sopNotPutInvoice': 'false',
'submitOrderParam.trackID': self.trackid,
'submitOrderParam.eid': self.eid,
'submitOrderParam.fp': self.fp,
}
order_url = 'http://trade.jd.com/shopping/order/submitOrder.action'
rp = self.sess.post(order_url, params=payload, cookies = self.cookies)
if rp.status_code == 200:
js = json.loads(rp.text)
if js['success'] == True:
print (u'下单成功!订单号:{0}'.format(js['orderId']))
print (u'请前往东京官方商城付款')
return True
else:
print (u'下单失败!<{0}: {1}>'.format(js['resultCode'], js['message']))
if str(js['message']).find('活动已经结束了')>0:
self.stop = True
return False
if str(js['message']).find('正在参与抢购活动,请重新')>0:
#<600126: 抱歉,xxx正在参与抢购活动,请重新回到商品详情页,使用“立即抢购”进行购买>
self.stop = True
return False
if js['resultCode'] == '60017':
# 60017: 您多次提交过快,请稍后再试
time.sleep(1)
else:
print (u'请求失败. StatusCode:', rp.status_code)
except Exception as e:
print ('Exp {0} : {1}'.format(FuncName(), e))
return False
def invertedTime_m(time_num):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
begintime = datetime.datetime.strptime(time_num, '%Y-%m-%d %H:%M:%S %f')
time1 = (begintime + datetime.timedelta(seconds=-100)).strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 100 秒,延时 60 秒。目标时间:", time_num)
while now < time1:
time.sleep(60)
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 100 秒,延时 60 秒。目标时间:",time_num)
def invertedTime_s(time_num):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
begintime = datetime.datetime.strptime(time_num, '%Y-%m-%d %H:%M:%S %f')
time1 = (begintime + datetime.timedelta(seconds=-3)).strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 3 秒,延时 1 秒。目标时间:", time_num)
while now < time1:
time.sleep(1)
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 3 秒,延时 1 秒。目标时间:",time_num)
def invertedTime_ms(time_num):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
begintime = datetime.datetime.strptime(time_num, '%Y-%m-%d %H:%M:%S %f')
time2 = (begintime + datetime.timedelta(seconds=-0.7)).strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 0.7 秒,延时 0.1 秒。目标时间:", time_num)
while now < time2:
time.sleep(0.1)
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "离开始时间大于 0.7 秒,延时 0.1 秒。目标时间:",time_num)
def run(jd,item,options):
options.good = item["skuid"]
options.stime = item["stime"]
yuyuemsg = item["yuyuemsg"]
if options.good == '':
return
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
print(now, "商品", item["skuid"], "目标时间:", item["stime"], item["skuname"])
begindatetime = datetime.datetime.strptime(options.stime, '%Y-%m-%d %H:%M:%S %f')
cart_scheduled_time = (begindatetime + datetime.timedelta(seconds=-1)).strftime(
'%Y-%m-%d %H:%M:%S %f') # 考虑到网络延时,可以提前xx毫秒
tmptime = datetime.datetime.strptime(cart_scheduled_time, '%Y-%m-%d %H:%M:%S %f')
end_time = (tmptime + datetime.timedelta(seconds=+2)).strftime('%Y-%m-%d %H:%M:%S %f') #
seckill_scheduled_time = (begindatetime + datetime.timedelta(seconds=-0.1)).strftime(
'%Y-%m-%d %H:%M:%S %f') # 考虑到网络延时,可以提前xx毫秒
# tmptime = datetime.datetime.strptime(seckill_scheduled_time, '%Y-%m-%d %H:%M:%S %f')
# end_time = (tmptime + datetime.timedelta(seconds=+1)).strftime('%Y-%m-%d %H:%M:%S %f') #
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
if now > end_time:
print(now, "商品", options.good, "当前时间已过抢购时间", seckill_scheduled_time)
return
# 预约
if yuyuemsg.lower() == 'yushou':
yyres, yymsg = jd.good_yuyue(options.good)
print(now, "商品", options.good, yymsg)
# 等待
invertedTime_m(options.stime)
invertedTime_s(options.stime)
invertedTime_ms(options.stime)
# 开始抢购
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
jd.stop = False
if yuyuemsg.lower().find('yushou') >= 0:
# seckill model
print("开始时间", seckill_scheduled_time)
print("结束时间", end_time)
if now >= end_time:
print(datetime.datetime.now(), "过点了,不要再抢了")
while now <= seckill_scheduled_time:
time.sleep(0.1)
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
while options.flush and now >= seckill_scheduled_time and now < end_time:
try:
if not jd.good_qiang1(options.good) and not jd.good_qiang2(options.good):
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
time.sleep(options.wait / 1000.0)
if jd.stop:
break
print(now, "再次尝试")
except Exception as e:
print('Exp {0} : {1}'.format(FuncName(), e))
else:
# cart model
if now >= end_time:
print(datetime.datetime.now(), "过点了,不要再抢了")
while now <= cart_scheduled_time:
time.sleep(0.1)
while options.flush and now >= cart_scheduled_time and now < end_time:
if not jd.buy(options) :
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')
time.sleep(options.wait / 1000.0)
if jd.stop:
break
print(now, "再次尝试")
return
def main(options):
#
jd = JDWrapper()
if not jd.checkLogin():
if not jd.login_by_QR():
return
# skuid|begintime|goodext
seckillgoods = {
"list": [
{"skuid": "3749111",
"skuname":'杜蕾斯 避孕套 男用 安全套 趁现在定制礼盒(AiR隐薄空气10+持久12+螺纹2+铁盒) 成人用品 Durex 169/3.4',
"stime": '2018-03-14 22:00:00 000',
"yuyuemsg":'yushou'
},
{"skuid": "14814288498",
"skuname": '四季沐歌(MICOE) 五合一无线遥控风暖浴霸集成吊顶吹风换气风暖led灯柔光照明带数显 经典即热即温四灯暖浴霸 789/1',
"stime": '2018-03-15 00:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "1523433344",
"skuname": '全棉时代(PurCotton) 生理盐水清洁棉 盒装水刺棉7.5x8cm 3盒 76.4/1',
"stime": '2018-03-15 10:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "4885644",
"skuname": '超活水 清洁剂 日本专利活性离子水 母婴除菌消毒专用 350ml 35.9/1',
"stime": '2018-03-15 14:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "5981493",
"skuname": '潘婷无硅油微米净透排浊赋能洗发水套装(洗发露300ml*2+护300ml+洗50ml+护50ml)(去油 强韧清爽) 89.9/19.9',
"stime": '2018-03-15 20:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "6012114",
"skuname": '普速 pusu 燃油宝浓缩型80ml 12支装 汽油添加剂 除积碳节油宝清洁剂 129/9.9',
"stime": '2018-03-15 22:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "1160762479",
"skuname": '希箭 799/9.9',
"stime": '2018-03-16 08:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "10130185444",
"skuname": '全棉时代(PurCotton)婴幼儿纱布肚围55x12cm 2条/袋 黄底蜜蜂+红小兔 55x12cm 67.3/1 234件',
"stime": '2018-03-16 10:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "4605019",
"skuname": '美的(Midea)破壁料理机智能高速加热破壁机 高速电机六叶破壁刀Power702 (一机双杯) /1 25件',
"stime": '2018-03-18 08:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "26145291881",
"skuname": '七匹狼 /1 140件',
"stime": '2018-03-18 22:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "26145291880",
"skuname": '七匹狼 140件',
"stime": '2018-03-18 22:00:00 000',
"yuyuemsg": 'yushou'
},
{"skuid": "",
"skuname": '',
"stime": '2018-03-19 22:00:00 000',
"yuyuemsg": 'yushou'
}
]
}
while True:
for item in seckillgoods["list"]:
run(jd,item,options)
good={}
good["skuid"]=input('Please input item id:')
good["skuname"] = input('Please input item name:')
good["stime"] = input('Please input begin time:')
good["yuyuemsg"] = str(input('Please input yushou flag:'))
if good["yuyuemsg"] == "1" :
good["yuyuemsg"]="yushou"
run(jd, good, options)
if __name__ == '__main__':
# help message
parser = argparse.ArgumentParser(description='Simulate to login Jing Dong, and buy sepecified good')
#parser.add_argument('-u', '--username',
# help='JD login user name', default='')
#parser.add_argument('-p', '--password',
# help='JD login user password', default='')
parser.add_argument('-a', '--area',
#help='Area string, like: 1_72_2799_0 for Beijing', default='1_72_2799_0')
help='Area string, like: 13_1007_3521_0 for Qingdao', default='13_1007_3521_0')
parser.add_argument('-g', '--good',
help='Jing Dong good ID', default='')
parser.add_argument('-c', '--count', type=int,
help='The count to buy', default=1)
parser.add_argument('-w', '--wait',
type=int, default=200,
help='Flush time interval, unit MS')
parser.add_argument('-f', '--flush',
action='store_true',
help='Continue flash if good out of stock')
parser.add_argument('-s', '--submit',
action='store_true',
help='Submit the order to Jing Dong')
parser.add_argument('-st', '--stime',
help='good start time to seckill') #
# example goods
hw_watch = '2567304'
iphone_7 = '497502'
options = parser.parse_args()
options.flush=True
options.submit=True
# options.good = '5353858' #5353858 东田(DONGTIAN)洗护套组 199
# options.good = '5716041' #Humana合满爱·欢满幼儿配方奶粉二段500g(6-12个月适用)(德国原装进口) 128
# options.good = '6359118' #惠氏(Wyeth)S-26铂臻学儿乐奶粉4段 瑞士进口 3-7岁幼儿配方 800克(罐装) 新包装 218
# options.good = '5571011' #锤子 坚果 Pro 2 碳黑色(细红线版) 全面屏双摄 4+32GB 全网通 移动联通电信4G手机 双卡双待 1699/1/12
# options.good = '4007899' #好奇 Huggies 心钻装 婴儿纸尿裤 新生儿尿不湿 NB66片【0-5kg】 179/1/180
# options.good = '4005851' #好奇 Huggies 金装成长裤 M56片 中号裤型纸尿裤【男女通用】【6-11kg】 76/1/ 2018-03-13 18:00:00 000
# options.good = '4720030' #杜蕾斯 189/1/4.3 2018-03-13 18:00:00 000
# options.good = '6390525' #Air
#options.good = '5966275' #惠氏(Wyeth)S-26艾智萌4段奶粉液态配方儿童奶 京东吉祥物定制版 整箱装(200毫升*15盒 )99/9.9/ 2018-03-14 20:00:00
# options.good = '3749111' #杜蕾斯 避孕套 男用 安全套 趁现在定制礼盒(AiR隐薄空气10+持久12+螺纹2+铁盒) 成人用品 Durex 169/3.4 2018-03-14 22:00:00
# options.good = '14814288498' # 四季沐歌(MICOE) 五合一无线遥控风暖浴霸集成吊顶吹风换气风暖led灯柔光照明带数显 经典即热即温四灯暖浴霸 789/1 2018-03-15 yushou
print (options)
# for test
if options.good == '':
options.good = iphone_7
'''
if options.password == '' or options.username == '':
print u'请输入用户名密码'
exit(1)
'''
main(options)
# j = JDWrapper()
# # j.good_stockone(options.good)
# if not j.checkLogin():
# if j.login_by_QR():
# j.good_yuyue(options.good)
# # j.good_qiang1(options.good)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。