cost_util.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. import json
  2. import requests
  3. import time
  4. import pymysql
  5. import logging
  6. import pandas
  7. from concurrent.futures import ThreadPoolExecutor
  8. from model.DataBaseUtils import MysqlUtils
  9. from model.ComUtils import *
  10. from model.DateUtils import DateUtils
  11. from PIL import Image
  12. from io import BytesIO
  13. from data_processing import video_processing
  14. du = DateUtils()
  15. db = MysqlUtils()
  16. max_workers = 10
  17. count = []
  18. t = du.get_n_days(-10)
  19. def get_campaign(account_id, access_token, flag, campaign_ids, dt):
  20. path = 'campaigns/get'
  21. fields = ('campaign_id', 'campaign_name', 'configured_status', 'campaign_type', 'promoted_object_type',
  22. 'daily_budget', 'budget_reach_date', 'created_time', 'last_modified_time', 'speed_mode', 'is_deleted')
  23. url = 'https://api.e.qq.com/v1.3/' + path
  24. li = []
  25. page = 1
  26. while True:
  27. parameters = {
  28. 'access_token': access_token,
  29. 'timestamp': int(time.time()),
  30. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  31. 'fields': fields,
  32. "filtering": [{
  33. "field": "campaign_id",
  34. "operator": "IN",
  35. "values":
  36. campaign_ids.split(',')
  37. }],
  38. "account_id": account_id,
  39. "page": page,
  40. "page_size": 100,
  41. "is_deleted": False
  42. }
  43. for k in parameters:
  44. if type(parameters[k]) is not str:
  45. parameters[k] = json.dumps(parameters[k])
  46. while True:
  47. r = requests.get(url, params=parameters, timeout=5).json()
  48. code = r['code']
  49. if code == 11017:
  50. time.sleep(61)
  51. else:
  52. break
  53. # logging.info(r)
  54. total_page = r['data']['page_info']['total_page']
  55. if page > total_page:
  56. break
  57. else:
  58. page += 1
  59. if r.get("data"):
  60. for i in r['data']['list']:
  61. li.append((str(i['campaign_id']), i['campaign_name'], i['configured_status'], i['campaign_type'],
  62. i['promoted_object_type'], i['daily_budget'], i.get('budget_reach_date'),
  63. DateUtils.stamp_to_str(i['created_time']),
  64. DateUtils.stamp_to_str(i['last_modified_time']), i.get('speed_mode'), i.get('is_deleted'),
  65. account_id, flag, dt))
  66. # logging.info(li)
  67. """mp 没有 speed_mode,is_deleted,budget_reach_date"""
  68. if li.__len__() > 0:
  69. logging.info(f"{account_id}有计划:" + str(li.__len__()))
  70. sql = "replace into campaign_info values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
  71. db.quchen_text.executeMany(sql, li)
  72. db.close()
  73. def get_adcreatives(account_id, access_token, flag, adc_ids, dt): # 获取创意
  74. # 接口 https://developers.e.qq.com/docs/api/adsmanagement/adcreatives/adcreatives_get?version=1.3
  75. url = 'https://api.e.qq.com/v1.1/adcreatives/get'
  76. li = []
  77. page = 1
  78. logging.info(f"{account_id}开始获取创意")
  79. while True:
  80. parameters = {
  81. 'access_token': access_token,
  82. 'timestamp': int(time.time()),
  83. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  84. 'fields': ('campaign_id', 'adcreative_id', 'adcreative_name', 'adcreative_elements', 'promoted_object_type',
  85. 'page_type',
  86. 'page_spec', 'link_page_spec', 'universal_link_url', 'promoted_object_id', 'site_set'),
  87. "filtering": [{
  88. "field": "adcreative_id",
  89. "operator": "IN",
  90. "values": adc_ids.split(',')
  91. }],
  92. "account_id": account_id,
  93. "page": page,
  94. "page_size": 100,
  95. "is_deleted": False
  96. }
  97. for k in parameters:
  98. if type(parameters[k]) is not str:
  99. parameters[k] = json.dumps(parameters[k])
  100. while True:
  101. h = requests.get(url, params=parameters, timeout=1)
  102. # logging.info(json.dumps(h.json(), ensure_ascii=False))
  103. if h.status_code == 200:
  104. r = h.json()
  105. # logging.info(r)
  106. break
  107. else:
  108. time.sleep(1)
  109. logging.info("爬取失败 等待1s")
  110. logging.info(f"{account_id}采集到创意")
  111. if 'data' in r.keys():
  112. is_video = 0
  113. for i in r['data']['list']:
  114. # logging.info(i)
  115. description = ''
  116. if flag == 'MP':
  117. if len(i['adcreative_elements']) > 0:
  118. d = i['adcreative_elements']
  119. title = d.get('title', '')
  120. description = d.get('description', '')
  121. if 'image' in d.keys():
  122. image = d.get('image', '')
  123. elif 'image_list' in d.keys():
  124. image = ','.join(d.get('image_list'))
  125. elif 'video' in d.keys():
  126. image = d['video']
  127. is_video = 1
  128. else:
  129. image = ''
  130. else:
  131. title = image = ''
  132. li.append((
  133. i['adcreative_id'], i['adcreative_name'], i['campaign_id'], image, title,
  134. i.get('promoted_object_type', ''), i.get('page_type', ''),
  135. i['page_spec'].get('page_id', ''), i.get('promoted_object_id', ''),
  136. '', description, 'MP', account_id, dt, is_video
  137. ))
  138. else:
  139. if len(i['adcreative_elements']) > 0:
  140. d = i['adcreative_elements']
  141. if 'image' in d.keys():
  142. image = d['image']
  143. elif 'element_story' in d.keys():
  144. image = ','.join([x['image'] for x in d['element_story']])
  145. else:
  146. image = ''
  147. title = d.get('title', '')
  148. description = d.get('description', '')
  149. else:
  150. image = title = description = ''
  151. li.append(
  152. (
  153. i['adcreative_id'], i['adcreative_name'], i['campaign_id'], image, title,
  154. i.get('promoted_object_type', ''), i.get('page_type', ''),
  155. i['page_spec'].get('page_id', ''), i.get('promoted_object_id', ''),
  156. ','.join(i['site_set']), description, 'GDT', account_id, dt, is_video
  157. )
  158. )
  159. total_page = r['data']['page_info']['total_page']
  160. if total_page > page:
  161. page += 1
  162. else:
  163. break
  164. else:
  165. break
  166. logging.info(f"{account_id}创意分析结束")
  167. logging.info(f"{account_id}获取创意,结束")
  168. if len(li) > 0:
  169. logging.info(f"{account_id}有创意:" + str(len(li)))
  170. sql = 'replace into adcreative_info values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) '
  171. db.quchen_text.executeMany(sql, li)
  172. def images_info_get(account_id, access_token, image_ids): # 获取图片信息
  173. # 接口 https://developers.e.qq.com/docs/api/business_assets/image/images_get?version=1.3
  174. def get_image_info(preview_url, err_num=5):
  175. try:
  176. if not preview_url:
  177. return None
  178. rsp = requests.get(preview_url, timeout=5)
  179. # 1.图片写入内存
  180. im = Image.open(BytesIO(rsp.content))
  181. # 2.获取图片属性
  182. image_format = im.format
  183. # image_size = len(rsp.content)
  184. return image_format
  185. except:
  186. if err_num < 5:
  187. return get_image_info(preview_url, err_num=err_num + 1)
  188. # 1.更新数据
  189. id_content = ','.join([''' '{}' '''.format(i) for i in image_ids.split(',')])
  190. id_content = id_content[:-1]
  191. sql = ''' select image_id from image_info vi
  192. where image_id in ({});'''.format(id_content)
  193. rs = db.quchen_text.getData(sql)
  194. id_all_set = set([i for i in image_ids.split(',') if len(i) > 0])
  195. id_have = set([i[0] for i in rs])
  196. image_ids = id_all_set - id_have
  197. fields = ('image_id', 'width', 'height', 'file_size', 'signature', 'preview_url')
  198. interface = 'images/get'
  199. url = 'https://api.e.qq.com/v1.3/' + interface
  200. page = 1
  201. li = []
  202. for image_id in image_ids:
  203. if len(image_id) < 1:
  204. continue
  205. while True:
  206. common_parameters = {
  207. 'access_token': access_token,
  208. 'timestamp': int(time.time()),
  209. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  210. 'fields': fields
  211. }
  212. parameters = {
  213. "account_id": account_id,
  214. "filtering": [{
  215. "field": "image_id",
  216. "operator": "IN",
  217. "values": [image_id]
  218. }],
  219. "page": page,
  220. "page_size": 100
  221. }
  222. parameters.update(common_parameters)
  223. for k in parameters:
  224. if type(parameters[k]) is not str:
  225. parameters[k] = json.dumps(parameters[k])
  226. while True:
  227. h = requests.get(url, params=parameters, timeout=5)
  228. # logging.info(h.text)
  229. if h.status_code == 200:
  230. r = h.json()
  231. break
  232. else:
  233. time.sleep(1)
  234. logging.info("请求出错 等待1s..")
  235. if 'data' in r.keys():
  236. li.extend(r['data']['list'])
  237. total_page = r['data']['page_info']['total_page']
  238. if total_page > page:
  239. page += 1
  240. else:
  241. break
  242. data = []
  243. for i in li:
  244. image_format = get_image_info(i['preview_url'])
  245. data.append(
  246. (i['image_id'], i['width'], i['height'], i['signature'], i['preview_url'], i['file_size'], image_format))
  247. logging.info(f"{account_id} 有新图片:" + str(li.__len__()))
  248. if li.__len__() > 0:
  249. sql = "insert IGNORE into image_info (image_id,width,height,signature,preview_url,size,type) value (%s,%s,%s,%s,%s,%s,%s)"
  250. db.quchen_text.executeMany(sql, data)
  251. db.close()
  252. def video_info_get(account_id, access_token, image_ids): # 获取视频信息
  253. # 接口 https://developers.e.qq.com/docs/api/business_assets/video/videos_get?version=1.3
  254. def get_video_info(video_url, signature, err_num=0):
  255. try:
  256. if not video_url:
  257. return None, None, None, None
  258. cloud_filepath, metadata_title, video_size, duration, bit_rate, width, height, format = video_processing.change_format(
  259. video_url, signature)
  260. return duration, bit_rate, metadata_title, cloud_filepath
  261. except Exception as e:
  262. logging.error(str(e))
  263. if err_num < 5:
  264. return get_video_info(video_url, signature, err_num=err_num + 1)
  265. else:
  266. return None, None, None, None
  267. # 1.数据库获取,查看是否需要获取对应数据
  268. id_content = ','.join([''' '{}' '''.format(i) for i in image_ids.split(',')])
  269. id_content = id_content[:-1]
  270. sql = ''' select video_id from video_info vi
  271. where video_id in ({});'''.format(id_content)
  272. rs = db.quchen_text.getData(sql)
  273. id_all_set = set([i for i in image_ids.split(',') if len(i) > 0])
  274. id_have = set([i[0] for i in rs])
  275. image_ids = id_all_set - id_have
  276. # 2.获取对应数据
  277. fields = ('video_id', 'width', 'height', 'file_size', 'signature', 'preview_url')
  278. interface = 'videos/get'
  279. url = 'https://api.e.qq.com/v1.3/' + interface
  280. page = 1
  281. li = []
  282. for image_id in image_ids:
  283. if len(image_id) < 1:
  284. continue
  285. while True:
  286. common_parameters = {
  287. 'access_token': access_token,
  288. 'timestamp': int(time.time()),
  289. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  290. 'fields': fields
  291. }
  292. parameters = {
  293. "account_id": account_id,
  294. "filtering": [{
  295. "field": "media_id",
  296. "operator": "IN",
  297. "values": [image_id]
  298. }],
  299. "page": page,
  300. "page_size": 100
  301. }
  302. parameters.update(common_parameters)
  303. for k in parameters:
  304. if type(parameters[k]) is not str:
  305. parameters[k] = json.dumps(parameters[k])
  306. while True:
  307. h = requests.get(url, params=parameters, timeout=5)
  308. # logging.info(h.text)
  309. if h.status_code == 200:
  310. r = h.json()
  311. break
  312. else:
  313. time.sleep(1)
  314. logging.info("请求出错 等待1s..")
  315. if 'data' in r.keys():
  316. li.extend(r['data']['list'])
  317. total_page = r['data']['page_info']['total_page']
  318. if total_page > page:
  319. page += 1
  320. else:
  321. break
  322. data = []
  323. for i in li:
  324. # TODO:signature相同的,不进行再一次运行计算
  325. duration, byte_rate, metadata_title, cloud_filepath = get_video_info(i['preview_url'], i['signature'])
  326. data.append((i['video_id'], i['width'], i['height'],
  327. i['signature'], i['preview_url'], i['file_size'],
  328. 'mp4', byte_rate, duration, metadata_title, cloud_filepath))
  329. logging.info(f"{account_id} 获取到新视频:" + str(li.__len__()))
  330. if li.__len__() > 0:
  331. sql = '''insert IGNORE into video_info (video_id,width,height,
  332. signature,preview_url,size,type,byte_rate,video_length,
  333. video_meta_data,download_path)
  334. value (%s,%s,%s,
  335. %s,%s,%s,%s,%s,%s,%s,%s)'''
  336. db.quchen_text.executeMany(sql, data)
  337. db.close()
  338. def ad_info():
  339. accounts = db.quchen_text.getData("""
  340. select account_id,access_token,name channel,'GDT' type from advertiser_qq where name !='' or name is not null
  341. union
  342. select account_id,access_token,name channel,'MP' type from advertiser_vx where name !='' or name is not null
  343. """)
  344. total_data = []
  345. executor = ThreadPoolExecutor(max_workers=max_workers)
  346. for i in accounts:
  347. # logging.info(i)
  348. account_id = i[0]
  349. access_token = i[1]
  350. type = i[3]
  351. executor.submit(get_ad_info, account_id, access_token, type, total_data)
  352. executor.shutdown()
  353. logging.info(len(total_data))
  354. if len(total_data) > 0:
  355. sql = "replace into ad_info values(%s,%s,%s,%s,%s,%s,%s) "
  356. db.quchen_text.executeMany(sql, total_data)
  357. """获取广告基础信息"""
  358. def get_ad_info(account_id, access_token, flag, ad_ids, dt):
  359. # 接口为 https://developers.e.qq.com/docs/apilist/ads/ad?version=1.3#a3
  360. path = 'ads/get'
  361. fields = ('ad_id', 'ad_name', 'adcreative_id', 'adgroup_id', 'campaign_id')
  362. url = 'https://api.e.qq.com/v1.3/' + path
  363. li = []
  364. page = 1
  365. while True:
  366. parameters = {
  367. 'access_token': access_token,
  368. 'timestamp': int(time.time()),
  369. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  370. 'fields': fields,
  371. "filtering": [{
  372. "field": "ad_id",
  373. "operator": "IN",
  374. "values":
  375. ad_ids.split(',')
  376. }],
  377. "account_id": account_id,
  378. "page": page,
  379. "page_size": 100,
  380. "is_deleted": False
  381. }
  382. for k in parameters:
  383. if type(parameters[k]) is not str:
  384. parameters[k] = json.dumps(parameters[k])
  385. while True:
  386. r = requests.get(url, params=parameters, timeout=5)
  387. r = r.json()
  388. code = r['code']
  389. if code == 11017:
  390. time.sleep(61)
  391. else:
  392. break
  393. # logging.info(r)
  394. total_page = r['data']['page_info']['total_page']
  395. if page > total_page:
  396. break
  397. else:
  398. page += 1
  399. if r.get("data"):
  400. for i in r['data']['list']:
  401. li.append((str(i['ad_id']), i['ad_name'], i['adcreative_id'], i['campaign_id'], i['adgroup_id'],
  402. account_id, flag, dt))
  403. if li.__len__() > 0:
  404. logging.info(f"{account_id}有广告:" + str(li.__len__()))
  405. sql = "replace into ad_info values(%s,%s,%s,%s,%s,%s,%s,%s) "
  406. db.quchen_text.executeMany(sql, li)
  407. db.close()
  408. def get_ad_cost_day(account_id, access_token, flag, st, et):
  409. if flag == 'MP':
  410. ad_cost_day_mp(account_id, access_token, st, et)
  411. else:
  412. ad_cost_day_gdt(account_id, access_token, st, et)
  413. def ad_cost_day_gdt(account_id, access_token, st, et):
  414. # 接口文档 https://developers.e.qq.com/docs/api/insights/ad_insights/daily_reports_get?version=1.3
  415. url = 'https://api.e.qq.com/v1.3/daily_reports/get'
  416. fields = (
  417. 'date', 'ad_id', 'adgroup_id', 'campaign_id', 'cost', 'view_count', 'ctr', 'follow_count', 'web_order_count',
  418. 'order_amount')
  419. li = []
  420. page = 1
  421. while True:
  422. parameters = {
  423. 'access_token': access_token,
  424. 'timestamp': int(time.time()),
  425. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  426. 'fields': fields,
  427. "account_id": account_id,
  428. "group_by": ['ad_id', 'date'],
  429. "level": 'REPORT_LEVEL_AD',
  430. "page": page,
  431. "page_size": 1000,
  432. "date_range": {
  433. "start_date": st,
  434. "end_date": et
  435. }
  436. }
  437. for k in parameters:
  438. if type(parameters[k]) is not str:
  439. parameters[k] = json.dumps(parameters[k])
  440. while True:
  441. r = requests.get(url, params=parameters, timeout=5)
  442. r = r.json()
  443. # logging.info(r)
  444. code = r['code']
  445. if code == 11017:
  446. time.sleep(61)
  447. else:
  448. break
  449. if r.get("data"):
  450. for i in r['data']['list']:
  451. if i['cost'] > 0:
  452. li.append(
  453. (
  454. i['date'], i['ad_id'],
  455. i['adgroup_id'], i['campaign_id'],
  456. i['cost'] / 100, i['view_count'],
  457. i['ctr'] * i['view_count'],
  458. i['follow_count'], i['web_order_count'],
  459. i['order_amount'] / 100, account_id, 'GDT'
  460. )
  461. )
  462. total_page = r['data']['page_info']['total_page']
  463. if page >= total_page:
  464. break
  465. else:
  466. page += 1
  467. # logging.info(li)
  468. if len(li) > 0:
  469. # 对一下ad的数据
  470. li_df = pandas.DataFrame(li)
  471. li_df_g = li_df.groupby([0, 1, 10, 11])
  472. li_new = []
  473. adgroup_id_dict = {}
  474. campaign_id_dict = {}
  475. for index, group in li_df_g:
  476. adgroup_id_dict[index] = ','.join(set([str(i) for i in group[2].tolist()][:20]))
  477. campaign_id_dict[index] = ','.join(set([str(i) for i in group[3].tolist()][:20]))
  478. for index, row in li_df_g.agg('sum').iterrows():
  479. new_row = row.tolist()
  480. new_row = list(index[0:2]) + new_row + list(index[2:])
  481. new_row[2] = adgroup_id_dict[index]
  482. new_row[3] = campaign_id_dict[index]
  483. li_new.append(tuple(new_row))
  484. logging.info(f"{account_id} have ad cost :{len(li_new)} ")
  485. db.quchen_text.executeMany('''replace into ad_cost_day(dt,ad_id,
  486. adgroup_id,campaign_id,cost,view_count,click_count,follow_count,
  487. order_count,order_amount,
  488. account_id,type) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)''', li_new)
  489. db.close()
  490. def ad_cost_day_mp(account_id, access_token, st, et):
  491. # 接口文档 https://developers.e.qq.com/docs/api/insights/ad_insights/daily_reports_get?version=1.3
  492. url = 'https://api.e.qq.com/v1.3/daily_reports/get'
  493. fields = ('date', 'ad_id', 'adgroup_id', 'cost', 'view_count', 'valid_click_count', 'official_account_follow_count',
  494. 'order_count', 'order_amount', 'campaign_id')
  495. li = []
  496. page = 1
  497. while True:
  498. parameters = {
  499. 'access_token': access_token,
  500. 'timestamp': int(time.time()),
  501. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  502. 'fields': fields,
  503. "account_id": account_id,
  504. "level": 'REPORT_LEVEL_AD_WECHAT',
  505. "page": page,
  506. "page_size": 1000,
  507. "date_range": {
  508. "start_date": st,
  509. "end_date": et
  510. }
  511. }
  512. for k in parameters:
  513. if type(parameters[k]) is not str:
  514. parameters[k] = json.dumps(parameters[k])
  515. while True:
  516. r = requests.get(url, params=parameters, timeout=5)
  517. r = r.json()
  518. # logging.info(r['data']['list'])
  519. # import pandas as pd
  520. # logging.info(pd.DataFrame(r['data']['list']))
  521. code = r['code']
  522. if code == 11017:
  523. time.sleep(61)
  524. else:
  525. break
  526. if r.get("data"):
  527. for i in r['data']['list']:
  528. if i['cost'] > 0:
  529. li.append(
  530. (
  531. i['date'], i['ad_id'],
  532. i['adgroup_id'], i['campaign_id'],
  533. i['cost'] / 100, i['view_count'],
  534. i['valid_click_count'],
  535. i['official_account_follow_count'],
  536. i['order_count'], i['order_amount'] / 100, account_id,
  537. 'MP'
  538. )
  539. )
  540. total_page = r['data']['page_info']['total_page']
  541. if page >= total_page:
  542. break
  543. else:
  544. page += 1
  545. # logging.info(li)
  546. if len(li) > 0:
  547. # 对一下ad的数据
  548. li_df = pandas.DataFrame(li)
  549. li_df_g = li_df.groupby([0, 1, 10, 11])
  550. li_new = []
  551. adgroup_id_dict = {}
  552. campaign_id_dict = {}
  553. for index, group in li_df_g:
  554. adgroup_id_dict[index] = ','.join(set([str(i) for i in group[2].tolist()][:20]))
  555. campaign_id_dict[index] = ','.join(set([str(i) for i in group[3].tolist()][:20]))
  556. for index, row in li_df_g.agg('sum').iterrows():
  557. new_row = row.tolist()
  558. new_row = list(index[0:2]) + new_row + list(index[2:])
  559. # new_row = new_row[:2] + new_row[4:]
  560. new_row[2] = adgroup_id_dict[index]
  561. new_row[3] = campaign_id_dict[index]
  562. li_new.append(tuple(new_row))
  563. logging.info(f"{account_id} have ad cost :{len(li_new)} ")
  564. db.quchen_text.executeMany('''replace into ad_cost_day(dt,ad_id,
  565. adgroup_id,campaign_id,cost,
  566. view_count,click_count,follow_count,order_count,order_amount,
  567. account_id,type) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)''', li_new)
  568. db.close()
  569. def daily_reports_get(access_token, account_id, level, start_date, end_date, fields): # 获取wx投放计划日报数据
  570. interface = 'daily_reports/get'
  571. url = 'https://api.e.qq.com/v1.3/' + interface
  572. common_parameters = {
  573. 'access_token': access_token,
  574. 'timestamp': int(time.time()),
  575. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  576. 'fields': fields
  577. }
  578. parameters = {
  579. "account_id": account_id,
  580. "level": level,
  581. "date_range":
  582. {
  583. "start_date": start_date,
  584. "end_date": end_date
  585. },
  586. "page": 1,
  587. "page_size": 1000,
  588. "fields":
  589. [
  590. ]
  591. }
  592. parameters.update(common_parameters)
  593. for k in parameters:
  594. if type(parameters[k]) is not str:
  595. parameters[k] = json.dumps(parameters[k])
  596. while True:
  597. r = requests.get(url, params=parameters, timeout=5)
  598. if r.status_code == 200:
  599. break
  600. else:
  601. time.sleep(1)
  602. logging.info("请求出错 等待1s..")
  603. return r.json()
  604. def daily_qq_reports_get(access_token, account_id, compaign_id, level, start_date, end_date, fields): # 获取gdt投放计划日报数据
  605. interface = 'daily_reports/get'
  606. url = 'https://api.e.qq.com/v1.1/' + interface
  607. common_parameters = {
  608. 'access_token': access_token,
  609. 'timestamp': int(time.time()),
  610. 'nonce': str(time.time()) + str(random.randint(0, 999999)),
  611. 'fields': fields
  612. }
  613. parameters = {
  614. "account_id": account_id,
  615. "filtering":
  616. [
  617. {
  618. "field": "campaign_id",
  619. "operator": "EQUALS",
  620. "values":
  621. [
  622. compaign_id
  623. ]
  624. }
  625. ],
  626. "level": level,
  627. "date_range":
  628. {
  629. "start_date": start_date,
  630. "end_date": end_date
  631. },
  632. "page": 1,
  633. "page_size": 1000,
  634. "fields":
  635. [
  636. ]
  637. }
  638. parameters.update(common_parameters)
  639. for k in parameters:
  640. if type(parameters[k]) is not str:
  641. parameters[k] = json.dumps(parameters[k])
  642. r = requests.get(url, params=parameters, timeout=5)
  643. return r.json()
  644. def mysql_insert_adcreative(data):
  645. db = pymysql.connect('rm-bp1c9cj79872tx3aaro.mysql.rds.aliyuncs.com', 'superc', 'Cc719199895', 'quchen_text')
  646. cursor = db.cursor()
  647. sql = 'replace into adcreative (campaign_id,adcreative_id,adcreative_name,image_id,title,promoted_object_type,page_type,page_id,link_page_id,promoted_object_id) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
  648. try:
  649. cursor.executemany(sql, data)
  650. db.commit()
  651. logging.info('insert [adcreative] ' + str(len(data)))
  652. except:
  653. db.rollback()
  654. logging.info('insert [adcreative] defeat')
  655. if __name__ == '__main__':
  656. account_id = 19206910
  657. access_token = '89079ccc8db047b078a0108e36a7e276'
  658. #
  659. account_id2 = 14709511
  660. access_token2 = 'e87f7b6f860eaeef086ddcc9c3614678'
  661. get_ad_cost_day(account_id, access_token, 'MP', '2021-04-09', '2021-04-09')
  662. # get_adcreatives(account_id,access_token,'MP','3187867673','2021-04-09')