check_order.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. __title__ = '每日凌晨空闲时检查本地数据库中的订单数据是否和平台昨天总订单一致'
  5. @Time : 2020/9/26 19:44
  6. @Author : Kenny-PC
  7. @Software: PyCharm
  8. # code is far away from bugs with the god animal protecting
  9. I love animals. They taste delicious.
  10. ┏┓ ┏┓
  11. ┏┛┻━━━┛┻┓
  12. ┃ ☃ ┃
  13. ┃ ┳┛ ┗┳ ┃
  14. ┃ ┻ ┃
  15. ┗━┓ ┏━┛
  16. ┃ ┗━━━┓
  17. ┃ 神兽保佑 ┣┓
  18. ┃ 永无BUG! ┏┛
  19. ┗┓┓┏━┳┓┏┛
  20. ┃┫┫ ┃┫┫
  21. ┗┻┛ ┗┻┛
  22. """
  23. import requests
  24. import hashlib
  25. import time
  26. import datetime
  27. from urllib import parse
  28. import math
  29. import pymysql
  30. from apscheduler.schedulers.blocking import BlockingScheduler
  31. import account_list as al
  32. from util import date_util, platform_util
  33. def md5value(s):
  34. md5 = hashlib.md5()
  35. md5.update(s.encode("utf-8"))
  36. return md5.hexdigest()
  37. ##《1》阅文
  38. def get_yuewen_order(st, et):
  39. url = 'https://open.yuewen.com/cpapi/wxRecharge/querychargelog'
  40. version = 1
  41. secert_list = al.yuewen_account_list
  42. for secert in secert_list:
  43. start_time = st
  44. email = secert[0]
  45. appsecert = secert[1]
  46. for i in range(int((et - st) / 86400)):
  47. # time.sleep(61)
  48. t = ()
  49. end_time = min(start_time + 86400, et)
  50. timestamp = int(time.time())
  51. s = ''
  52. page = 1
  53. order_status = 2
  54. data = {
  55. 'email': email,
  56. 'version': version,
  57. 'timestamp': timestamp,
  58. 'start_time': start_time,
  59. 'end_time': end_time,
  60. 'page': page,
  61. 'order_status': order_status
  62. # 'last_min_id':last_min_id,
  63. # 'last_max_id':last_max_id,
  64. # 'total_count':total_count,
  65. # 'last_page':last_page
  66. }
  67. sorted_data = sorted(data.items())
  68. for k, v in sorted_data:
  69. s = s + str(k) + str(v)
  70. sign = md5value(appsecert + s).upper()
  71. data1 = {
  72. 'email': email,
  73. 'version': version,
  74. 'timestamp': timestamp,
  75. 'start_time': start_time,
  76. 'end_time': end_time,
  77. 'page': page,
  78. 'order_status': order_status,
  79. 'sign': sign
  80. }
  81. list1 = requests.get(url=url, params=data1)
  82. total_count = list1.json()['data']['total_count']
  83. last_min_id = list1.json()['data']['min_id']
  84. last_max_id = list1.json()['data']['max_id']
  85. last_page = list1.json()['data']['page']
  86. if total_count > 0:
  87. for x in list1.json()['data']['list']:
  88. y = {}
  89. dtime = datetime.datetime.strptime(x['order_time'], "%Y-%m-%d %H:%M:%S")
  90. y['date'] = ((int(time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
  91. y['platform'] = '阅文'
  92. y['channel'] = x['app_name']
  93. y['from_novel'] = x['book_name']
  94. y['user_id'] = x['openid']
  95. y['stage'] = ''
  96. y['channel_id'] = 0
  97. y['order_time'] = x['order_time']
  98. y['amount'] = x['amount']
  99. y['reg_time'] = x['reg_time']
  100. y['order_id'] = x['order_id']
  101. """
  102. del x['app_name']
  103. del x['order_status']
  104. del x['order_type']
  105. del x['openid']
  106. del x['user_name']
  107. del x['sex']
  108. del x['channel_name']
  109. del x['book_id']
  110. del x['book_name']
  111. del x['report_status']
  112. """
  113. y = sorted(y.items(), key=lambda item: item[0])
  114. y = dict(y)
  115. y = tuple(y.values())
  116. t = t + ((y),)
  117. if total_count > 100:
  118. for page in range(2, math.ceil(total_count / 100) + 1):
  119. data = {
  120. 'email': email,
  121. 'version': version,
  122. 'timestamp': timestamp,
  123. 'start_time': start_time,
  124. 'end_time': end_time,
  125. 'page': page,
  126. 'last_min_id': last_min_id,
  127. 'last_max_id': last_max_id,
  128. 'total_count': total_count,
  129. 'last_page': last_page,
  130. 'order_status': order_status
  131. }
  132. sorted_data = sorted(data.items())
  133. s1 = ''
  134. for k, v in sorted_data:
  135. s1 = s1 + str(k) + str(v)
  136. sign = md5value(appsecert + s1).upper()
  137. data2 = {
  138. 'email': email,
  139. 'version': version,
  140. 'timestamp': timestamp,
  141. 'start_time': start_time,
  142. 'end_time': end_time,
  143. 'page': page,
  144. 'last_min_id': last_min_id,
  145. 'last_max_id': last_max_id,
  146. 'total_count': total_count,
  147. 'last_page': last_page,
  148. 'order_status': order_status,
  149. 'sign': sign
  150. }
  151. list2 = requests.get(url=url, params=data2)
  152. for x in list2.json()['data']['list']:
  153. y = {}
  154. dtime = datetime.datetime.strptime(x['order_time'], "%Y-%m-%d %H:%M:%S")
  155. y['date'] = ((int(time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
  156. y['platform'] = '阅文'
  157. y['channel'] = x['app_name']
  158. y['from_novel'] = x['book_name']
  159. y['user_id'] = x['openid']
  160. y['stage'] = ''
  161. y['channel_id'] = 0
  162. y['order_time'] = x['order_time']
  163. y['amount'] = x['amount']
  164. y['reg_time'] = x['reg_time']
  165. y['order_id'] = x['order_id']
  166. """
  167. del x['app_name']
  168. del x['order_status']
  169. del x['order_type']
  170. del x['openid']
  171. del x['user_name']
  172. del x['sex']
  173. del x['channel_name']
  174. del x['book_id']
  175. del x['book_name']
  176. del x['report_status']
  177. """
  178. y = sorted(y.items(), key=lambda item: item[0])
  179. y = dict(y)
  180. y = tuple(y.values())
  181. t = t + ((y),)
  182. total_count = list2.json()['data']['total_count']
  183. last_min_id = list2.json()['data']['min_id']
  184. last_max_id = list2.json()['data']['max_id']
  185. last_page = list2.json()['data']['page']
  186. print(email, start_time, len(t))
  187. start_time = start_time + 86400
  188. if len(t) > 0:
  189. mysql_insert_order(t)
  190. ##《2》掌读
  191. def get_zhangdu_order(st, et):
  192. secert_list = al.zhangdu_account_list
  193. url = 'https://api.zhangdu520.com/channel/getorder'
  194. for item in secert_list: # 分渠道
  195. t = ()
  196. uid = item[0]
  197. appsecert = item[1]
  198. channel = item[2]
  199. timestamp = int(time.time())
  200. sign = md5value(str(uid) + '&' + appsecert + '&' + str(timestamp))
  201. page = 1
  202. starttime = st
  203. timespace = 90 * 3600 * 24
  204. endtime = min(et, st + timespace)
  205. for x in range((et - st) // timespace + 1): # 分时段
  206. Params = {
  207. 'uid': uid,
  208. 'timestamp': timestamp,
  209. 'sign': sign,
  210. 'starttime': starttime,
  211. 'endtime': endtime
  212. }
  213. list1 = requests.get(url=url, params=Params)
  214. pageCount = list1.json()['data']['pageCount']
  215. if pageCount > 0:
  216. for a in range(1, pageCount + 1): # 分页
  217. page = a
  218. Params = {
  219. 'uid': uid,
  220. 'timestamp': timestamp,
  221. 'sign': sign,
  222. 'starttime': starttime,
  223. 'endtime': endtime,
  224. 'page': page
  225. }
  226. list2 = requests.get(url=url, params=Params).json()
  227. if 'data' in list2.keys():
  228. for b in list2['data']['list']:
  229. c = {}
  230. c['amount'] = b['amount']
  231. c['channel_id'] = uid
  232. c['order_id'] = str(b['orderno'])
  233. c['order_time'] = b['ctime']
  234. c['user_id'] = b['openid']
  235. c['platform'] = '掌读'
  236. c['channel'] = channel
  237. c['reg_time'] = b['regtime']
  238. c['from_novel'] = ''
  239. c['stage'] = ''
  240. c['date'] = ((int(b['ctime']) + 8 * 3600) // 86400) * 86400 - 8 * 3600
  241. """
  242. del b['openid']
  243. del b['regtime']
  244. del b['ip']
  245. del b['ua']
  246. del b['id']
  247. del b['ctime']
  248. del b['userid']
  249. del b['orderno']
  250. del b['source']
  251. del b['sourceid']
  252. """
  253. if b['status'] == '1':
  254. # del b['status']
  255. del b
  256. x = sorted(c.items(), key=lambda item: item[0])
  257. x = dict(x)
  258. x = tuple(x.values())
  259. t = t + ((x),)
  260. else:
  261. print(list2)
  262. starttime = starttime + timespace
  263. endtime = min(et, starttime + timespace)
  264. if len(t) > 0:
  265. mysql_insert_order(t)
  266. print('掌读', channel, len(t))
  267. ##《3》花生
  268. def get_huasheng_order(st, et):
  269. apikey_list = al.huasheng_account_list
  270. url = 'https://vip.rlcps.cn/api/getMerchants'
  271. for key in apikey_list: # 获取每个vip账号下的channel_id
  272. apiKEY = key[0]
  273. apiSecurity = key[1]
  274. stage = key[2]
  275. timestamp = str(int(time.time()))
  276. sign = md5value(apiKEY + timestamp + apiSecurity).upper()
  277. data = {
  278. 'apiKey': apiKEY,
  279. 'apiSecurity': apiSecurity,
  280. 'timestamp': timestamp,
  281. 'sign': sign
  282. }
  283. list0 = requests.post(url, data).json()
  284. t = ()
  285. for merchant in list0['data']:
  286. merchant_id = merchant['merchant_id']
  287. merchant_name = merchant['merchant_name']
  288. url1 = 'https://vip.rlcps.cn/api/orderList'
  289. start_time = st
  290. for i in range((et - st) // 86400):
  291. page = 1
  292. date = time.strftime("%Y-%m-%d", time.localtime(start_time))
  293. sign = md5value(apiKEY + date + str(merchant_id) + timestamp + apiSecurity).upper()
  294. data1 = {
  295. 'apiKey': apiKEY,
  296. 'apiSecurity': apiSecurity,
  297. 'timestamp': timestamp,
  298. 'date': date,
  299. 'merchant_id': merchant_id,
  300. 'sign': sign,
  301. 'page': page
  302. }
  303. list1 = requests.post(url1, data1).json()
  304. if 'data' in list1.keys() and len(list1['data']) > 0:
  305. for i in range(int(math.ceil(list1['count'] / 500))):
  306. data2 = {
  307. 'apiKey': apiKEY,
  308. 'apiSecurity': apiSecurity,
  309. 'timestamp': timestamp,
  310. 'date': date,
  311. 'merchant_id': merchant_id,
  312. 'sign': sign,
  313. 'page': page
  314. }
  315. list2 = requests.post(url1, data2).json()
  316. for x in list2['data']:
  317. if x['order_status'] == 1:
  318. y = {}
  319. ##dtime = datetime.datetime.strptime(x['pay_at'],"%Y-%m-%d")
  320. ##y['date']= ((int(time.mktime(dtime.timetuple()))+8*3600)//86400)*86400-8*3600
  321. y['user_id'] = x['openid']
  322. y['order_id'] = x['trans_id']
  323. y['order_time'] = x['pay_at']
  324. y['reg_time'] = x['join_at']
  325. y['date'] = (start_time + 8 * 3600) // 86400 * 86400 - 8 * 3600
  326. y['channel'] = merchant_name
  327. y['channel_id'] = merchant_id
  328. y['platform'] = '花生'
  329. y['stage'] = stage
  330. y['from_novel'] = x['book_name']
  331. y['amount'] = x['amount']
  332. """
  333. del x['order_num']
  334. del x['book_name']
  335. del x['trans_id']
  336. del x['pay_at']
  337. del x['join_at']
  338. del x['subscribe_at']
  339. del x['openid']
  340. del x['charge_count']
  341. del x['book_id']
  342. del x['order_status']
  343. del x['user_name']
  344. del x['spread_name']
  345. del x['request_at']
  346. """
  347. y = sorted(y.items(), key=lambda item: item[0])
  348. y = dict(y)
  349. y = tuple(y.values())
  350. t = t + ((y),)
  351. page = page + 1
  352. else:
  353. print(list1)
  354. start_time = start_time + 86400
  355. if len(t) > 0:
  356. mysql_insert_order(t)
  357. print(stage, merchant_name, len(t))
  358. ##《4》掌中云
  359. def get_zzy_order(st, et):
  360. # 掌中云的时间格式比较特殊,转换下
  361. st = platform_util.getZzyQueryTime(st)
  362. et = platform_util.getZzyQueryTime(et)
  363. API_list = al.zzy_account_list
  364. url = 'https://openapi.818tu.com/partners/channel/channels/list?'
  365. for x in API_list:
  366. my_key = x[0]
  367. secert = x[1]
  368. stage = x[2]
  369. my_sign = md5value(secert + 'key=' + my_key)
  370. parameter = 'key=' + my_key + '&sign=' + my_sign
  371. print(url + parameter)
  372. channel_list = requests.get(url + parameter) # 获取子渠道列表
  373. if 'data' in channel_list.json().keys():
  374. items = channel_list.json()['data']['items']
  375. elif len(x) > 3:
  376. my_key = x[3]
  377. secert = x[4]
  378. my_sign = md5value(secert + 'key=' + my_key)
  379. parameter = 'key=' + my_key + '&sign=' + my_sign
  380. channel_list = requests.get(url + parameter)
  381. items = channel_list.json()['data']['items']
  382. else:
  383. print(channel_list.json())
  384. items = []
  385. for item in items: # 获取channel_id 后逐个拉取历史orders
  386. r = ()
  387. channel_id = item['id']
  388. channel = item['nickname']
  389. status = str(1)
  390. per_page = str(1000)
  391. limit_time = et
  392. get_time = st
  393. lt = parse.urlencode({'created_at[lt]': limit_time})
  394. gt = parse.urlencode({'created_at[gt]': get_time})
  395. url_1 = 'https://openapi.818tu.com/partners/channel/orders/list?'
  396. my_sign_1 = md5value(secert + 'channel_id=' + str(
  397. channel_id) + '&created_at[gt]=' + get_time + '&created_at[lt]=' + limit_time + '&key=' + my_key + '&per_page=' + per_page + '&status=' + status)
  398. parameter_1 = 'channel_id=' + str(
  399. channel_id) + '&' + gt + '&' + lt + '&per_page=' + per_page + '&status=' + status + '&key=' + my_key + '&sign=' + my_sign_1
  400. orders = requests.get(url_1 + parameter_1)
  401. t = orders.json()['data']['count'] // int(per_page) + 1
  402. for page in range(1, t + 1):
  403. my_sign_2 = md5value(secert + 'channel_id=' + str(
  404. channel_id) + '&created_at[gt]=' + get_time + '&created_at[lt]=' + limit_time + '&key=' + my_key + '&page=' + str(
  405. page) + '&per_page=' + per_page + '&status=' + status)
  406. parameter_2 = 'channel_id=' + str(channel_id) + '&' + gt + '&' + lt + '&page=' + str(
  407. page) + '&per_page=' + per_page + '&status=' + status + '&key=' + my_key + '&sign=' + my_sign_2
  408. orders_1 = requests.get(url_1 + parameter_2)
  409. b = orders_1.json()['data']['items']
  410. for a in b:
  411. c = {}
  412. c['user_id'] = str(a['member']['openid'])
  413. c['channel'] = channel
  414. c['reg_time'] = a['member']['created_at']
  415. c['channel_id'] = channel_id
  416. c['amount'] = round(a['price'] / 100, 2)
  417. c['order_id'] = str(a['id'])
  418. c['order_time'] = a['created_at']
  419. c['platform'] = '掌中云'
  420. c['stage'] = stage
  421. # c['amount']=a['amount']
  422. dtime = datetime.datetime.strptime(a['created_at'][0:10], "%Y-%m-%d")
  423. c['date'] = ((int(time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
  424. if str(a['from_novel_id']) != 'None':
  425. c['from_novel'] = a['from_novel']['title']
  426. else:
  427. c['from_novel'] = 'None'
  428. """
  429. del a['member']
  430. del a['referral_link_id']
  431. del a['id']
  432. del a['created_at']
  433. del a['paid_at']
  434. del a['border_id']
  435. del a['from_novel_id']
  436. del a['status']
  437. del a['price']
  438. del a['agent_uid']
  439. """
  440. x = sorted(c.items(), key=lambda item: item[0])
  441. x = dict(x)
  442. x = tuple(x.values())
  443. r = r + ((x),)
  444. if len(r) > 0:
  445. mysql_insert_order(r)
  446. print('zzy', channel, len(r))
  447. ##《5》 悠书阁
  448. def get_ysg_order(st, et):
  449. key_list = al.ysg_account_list
  450. url = 'https://novel.youshuge.com/v2/open/orders'
  451. o = ()
  452. for key in key_list:
  453. host_name = key[0]
  454. channel_id = key[1]
  455. secert_key = key[2]
  456. channel = key[3]
  457. stage = key[4]
  458. timestamp = int(time.time())
  459. start_date = time.strftime("%Y-%m-%d", time.localtime(st))
  460. end_date = time.strftime("%Y-%m-%d", time.localtime(et))
  461. page = 1
  462. str1 = 'channel_id=' + str(channel_id) + '&end_date=' + end_date + '&host_name=' + host_name + '&page=' + str(
  463. page) + '&pay_status=1' + '&start_date=' + start_date + '&time=' + str(timestamp) + '&key=' + secert_key
  464. sign = md5value(str1).upper()
  465. data = {
  466. 'sign': sign,
  467. 'host_name': host_name,
  468. 'time': timestamp,
  469. 'channel_id': channel_id,
  470. 'page': page,
  471. 'pay_status': 1,
  472. 'start_date': start_date,
  473. 'end_date': end_date
  474. }
  475. r = requests.post(url, data).json()
  476. if 'data' in r.keys():
  477. if len(r['data']) > 0:
  478. for i in range((r['data'][0]['count'] - 1) // 100 + 1):
  479. timestamp = int(time.time())
  480. str1 = 'channel_id=' + str(
  481. channel_id) + '&end_date=' + end_date + '&host_name=' + host_name + '&page=' + str(
  482. page) + '&pay_status=1' + '&start_date=' + start_date + '&time=' + str(
  483. timestamp) + '&key=' + secert_key
  484. sign = md5value(str1).upper()
  485. data2 = {
  486. 'sign': sign,
  487. 'host_name': host_name,
  488. 'time': timestamp,
  489. 'channel_id': channel_id,
  490. 'page': page,
  491. 'pay_status': 1,
  492. 'start_date': start_date,
  493. 'end_date': end_date
  494. }
  495. r2 = requests.post(url, data2).json()
  496. if 'data' in r2.keys():
  497. if len(r2['data']) > 0:
  498. for x in r2['data']:
  499. y = {}
  500. dtime = datetime.datetime.strptime(x['create_time'][0:10], "%Y-%m-%d")
  501. y['date'] = ((int(
  502. time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
  503. y['order_id'] = x['order_num']
  504. y['amount'] = round(int(x['price']) / 100, 2)
  505. y['order_time'] = x['create_time']
  506. y['channel'] = channel
  507. y['from_novel'] = x['book_name']
  508. y['stage'] = stage
  509. y['user_id'] = x['openid']
  510. y['channel_id'] = channel_id
  511. y['platform'] = '悠书阁'
  512. y['reg_time'] = x['reg_time']
  513. y = sorted(y.items(), key=lambda item: item[0])
  514. y = dict(y)
  515. y = tuple(y.values())
  516. o = o + ((y),)
  517. page = page + 1
  518. if len(o) > 0:
  519. mysql_insert_order(o)
  520. ## 数据导入表采用replace替换主键orderid的方法
  521. def mysql_insert_order(data):
  522. pass
  523. # if len(data) != 0:
  524. # print('数据为空,不执行数据库操作!')
  525. # pass
  526. # else:
  527. # db = pymysql.connect('localhost', 'root', 'root', 'quchen_text')
  528. # cursor = db.cursor()
  529. # # sql = 'insert ignore into quchen_text.order_daily (amount,channel,channel_id,date,from_novel,order_id,order_time,platform,reg_time,stage,user_id) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);'
  530. # # sql = "update quchen_text.order set amount =%s where platform='掌中云' and order_id =%s"
  531. # sql = 'replace into quchen_text.order (amount,channel,channel_id,date,from_novel,order_id,order_time,platform,reg_time,stage,user_id) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);'
  532. #
  533. # try:
  534. # cursor.executemany(sql, data)
  535. # db.commit()
  536. # print('access insert order', len(data))
  537. # except Exception as e:
  538. # db.rollback()
  539. # print('订单数据入库失败:', e)
  540. def start_all_job():
  541. st_unix = date_util.getYesterdayStartTime()
  542. et_unix = date_util.getTodayStartTime()
  543. print(date_util.getSecondsToDatetime(st_unix))
  544. print(date_util.getSecondsToDatetime(et_unix))
  545. start_exec_seconds = date_util.getCurrentSecondTime()
  546. # get_yuewen_order(st_unix, et_unix)
  547. # get_ysg_order(st_unix, et_unix)
  548. # get_zhangdu_order(st_unix, et_unix)
  549. get_zzy_order(st_unix, et_unix)
  550. # get_huasheng_order(st_unix, et_unix)
  551. print('执行时间(秒)为:', date_util.getCurrentSecondTime() - start_exec_seconds)
  552. if __name__ == '__main__':
  553. start_all_job()
  554. #
  555. # scheduler = BlockingScheduler()
  556. #
  557. # #每天凌晨执行
  558. # #start_job_time = '2020-09-26 03:05:00'
  559. # # scheduler.add_job(start_all_job, 'interval', days=1, start_date=start_job_time)
  560. #
  561. # #每天凌晨3点到4点的30分钟都执行一次
  562. # # scheduler.add_job(start_all_job, 'cron', hour='3-4', minute='30')
  563. #
  564. # # 每10秒执行一次
  565. # scheduler.add_job(start_all_job, 'interval', seconds=2)
  566. # scheduler.start()