create_ad.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. from wechat_action.sql_tools import save_ad_layout_result
  2. from selenium.webdriver.support.wait import WebDriverWait
  3. from selenium.webdriver.common.keys import Keys
  4. from selenium.webdriver import ActionChains
  5. from sqlalchemy import Table
  6. from logging import handlers
  7. import logging
  8. import random
  9. import time
  10. import json
  11. import re
  12. import os
  13. class CreateAd:
  14. def __init__(self, login_ad, layout_db, user_id):
  15. self.user_id = user_id
  16. self.service_name = login_ad.service_name
  17. self.wechat_name = login_ad.wechat_name
  18. # self.driver = LogIn(service_name, wechat_name).get_driver_loged()
  19. self.driver = login_ad.get_driver_loged()
  20. self.get_into_create_page()
  21. self.db = layout_db
  22. self.metadata = self.db.metadata
  23. self.sql_session = self.db.DBSession()
  24. self.layout_table = Table('layout_record', self.metadata,
  25. autoload=True, autoload_with=self.db.engine)
  26. self.send_file_limit_num = 8
  27. def get_into_create_page(self):
  28. # 进入创建页面
  29. self.driver.find_element_by_id('material').click()
  30. WebDriverWait(self.driver, 10).until(lambda driver: driver.find_element_by_class_name('ui-fl-r'))
  31. time.sleep(random.uniform(0.1, 0.2))
  32. self.driver.find_element_by_class_name('ui-fl-r').click()
  33. WebDriverWait(self.driver, 5).until(lambda driver: driver.find_element_by_css_selector(
  34. '#wxadcontainer > div:nth-child(1) > div:nth-child(2) > div.dialog-1fj_N480ZT > div > div > div:nth-child(1) > div.dialogCardFooter-17KpBD1lgN > button'))
  35. self.driver.find_element_by_css_selector(
  36. '#wxadcontainer > div:nth-child(1) > div:nth-child(2) > div.dialog-1fj_N480ZT > div > div > div:nth-child(1) > div.dialogCardFooter-17KpBD1lgN > button').click()
  37. self.driver.switch_to.window(self.driver.window_handles[-1])
  38. WebDriverWait(self.driver, 100).until(lambda driver: driver.find_element_by_class_name('addContent-8pexaaAGYy'))
  39. self.driver.find_element_by_class_name('addContent-8pexaaAGYy').click()
  40. WebDriverWait(self.driver, 100).until(lambda driver: driver.find_element_by_class_name('topArea-qOwEAeNuIn'))
  41. def get_layout(self):
  42. # 数据库获取数据,然后进行编排
  43. # 创建编排
  44. pass
  45. def set_advertisement_sign(self):
  46. # 设置广告标记
  47. now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  48. self.driver.find_element_by_xpath('//*[@class="icon-edQB0KK2VG"]').click()
  49. input_element = self.driver.find_element_by_xpath('//input[@class="input-2lFnByGCRh"]')
  50. input_element.send_keys(Keys.BACKSPACE)
  51. input_element.send_keys(now_time)
  52. return now_time
  53. def set_background_color(self):
  54. color_buttons = self.driver.find_elements_by_class_name('adui-cp-picker')
  55. c_buttons_can_use = []
  56. for _ in color_buttons:
  57. if _.is_displayed() and _.is_enabled():
  58. c_buttons_can_use.append(_)
  59. c_buttons_can_use[0].click()
  60. time.sleep(random.uniform(0.2, 0.3))
  61. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  62. for _ in input_elements:
  63. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == 'FFFFFF':
  64. _.click()
  65. _.send_keys('F7F7F7')
  66. def set_head_assemb(self, info):
  67. def single_page_set():
  68. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/div[1]/div/div[1]/div/div').click()
  69. time.sleep(random.uniform(0.1, 0.2))
  70. file_name = os.path.basename(info_v)
  71. self.driver.find_element_by_class_name('upload-img-item-inner-2gsg7NjaZ8').click()
  72. WebDriverWait(self.driver, 10).until(
  73. lambda x: len([_ for _ in self.driver.find_elements_by_class_name('title-29sncpKgTl') if
  74. _.is_displayed() and _.is_enabled()]) > 0)
  75. turn_page_buttons = self.driver.find_elements_by_class_name('paginationIcon-1EfoH0sNRF')
  76. can_use_button = []
  77. for _ in turn_page_buttons:
  78. if _.is_enabled() and _.is_displayed():
  79. can_use_button.append(_)
  80. # 不断翻页获取到元素为止
  81. chose_over = False
  82. while True:
  83. page_elements = self.driver.find_elements_by_class_name('title-29sncpKgTl')
  84. for _ in page_elements:
  85. if _.is_displayed() and _.is_enabled():
  86. if file_name in _.text:
  87. _.click()
  88. chose_over = True
  89. break
  90. if chose_over or len(can_use_button) == 0:
  91. break
  92. # 翻到最后一页时停止
  93. page_text = self.driver.find_element_by_class_name('count_small-37CcvfzoTl').text
  94. page_nums = re.findall('\d+', page_text)
  95. if int(page_nums[0].strip()) == int(page_nums[1].strip()):
  96. break
  97. # 翻页
  98. can_use_button[2].click()
  99. # 确保翻页成功
  100. WebDriverWait(self.driver, 10).until(
  101. lambda x: page_text != self.driver.find_element_by_class_name('count_small-37CcvfzoTl').text)
  102. self.driver.find_element_by_xpath('//*[@id="test_material_container_confirm"]').click()
  103. try:
  104. WebDriverWait(self.driver, 4).until(
  105. lambda driver: driver.find_element_by_class_name(
  106. 'btnFist-uueBS6DQFa'))
  107. _ = self.driver.find_element_by_class_name(
  108. 'btnFist-uueBS6DQFa')
  109. WebDriverWait(self.driver, 4).until(
  110. lambda x: (_.is_displayed() and _.is_enabled()))
  111. time.sleep(1)
  112. _.click()
  113. WebDriverWait(self.driver, 100).until(
  114. lambda driver: driver.find_element_by_class_name(
  115. 'btn-3E823IXt3m'))
  116. _ = self.driver.find_element_by_class_name(
  117. 'btn-3E823IXt3m')
  118. WebDriverWait(self.driver, 100).until(
  119. lambda x: (_.is_displayed() and _.is_enabled()))
  120. time.sleep(1)
  121. _.click()
  122. except Exception as e:
  123. pass
  124. logging.info('头版首页单图上传结束')
  125. def multi_page_set():
  126. self.driver.find_element_by_css_selector(
  127. '#stage-sidebar > div.topArea-qOwEAeNuIn > div > div:nth-child(2)').click()
  128. time.sleep(random.uniform(0.1, 0.2))
  129. page_size = len(info_v)
  130. if page_size == 3:
  131. pass
  132. if page_size == 4:
  133. self.driver.find_element_by_css_selector(
  134. '#stage-settings > div:nth-child(1) > div > div > div:nth-child(3) > div.adui-form-item > div.adui-form-control > div > button:nth-child(2)').click()
  135. if page_size == 6:
  136. self.driver.find_element_by_css_selector(
  137. '#stage-settings > div:nth-child(1) > div > div > div:nth-child(3) > div.adui-form-item > div.adui-form-control > div > button:nth-child(3)').click()
  138. time.sleep(random.uniform(0.1, 0.2))
  139. self.driver.find_element_by_class_name('imageUploadItem-tA9JX0RWua').click()
  140. WebDriverWait(self.driver, 1000).until(
  141. lambda driver: self.driver.find_element_by_class_name('adui-tabs-tab')
  142. )
  143. input_elements = self.driver.find_elements_by_tag_name('input')
  144. input_find_element = None
  145. for _ in input_elements:
  146. if '输入关键词搜索素材' in _.get_attribute('placeholder'):
  147. input_find_element = _
  148. for _ in info_v:
  149. file_name = os.path.basename(_)
  150. logging.info(file_name)
  151. input_find_element.send_keys(file_name)
  152. input_find_element.send_keys(Keys.RETURN)
  153. WebDriverWait(self.driver, 1000).until(
  154. lambda driver: driver.find_element_by_class_name('img-2HvhMmpnzP'))
  155. file_element = self.driver.find_element_by_class_name('img-2HvhMmpnzP')
  156. WebDriverWait(self.driver, 1000).until(
  157. lambda x: (file_element.is_displayed() and file_element.is_enabled()))
  158. ActionChains(self.driver).move_to_element(file_element).perform()
  159. time.sleep(random.uniform(0.5, 1))
  160. file_element.click()
  161. for i in range(len(file_name) + 10):
  162. input_find_element.send_keys(Keys.BACKSPACE)
  163. time.sleep(random.uniform(0.5, 1))
  164. self.driver.find_element_by_xpath('/html/body/div[12]/div/div/div[2]/div/div[3]/button[2]').click()
  165. # 切图操作如果有的话进行对应操作.
  166. for i in range(len(info_v) + 1):
  167. try:
  168. WebDriverWait(self.driver, 6).until(
  169. lambda driver: driver.find_element_by_xpath(
  170. '/html/body/div[13]/div/div/div[2]/div/div[3]/button[2]'))
  171. self.driver.find_element_by_xpath('/html/body/div[13]/div/div/div[2]/div/div[3]/button[2]').click()
  172. except:
  173. pass
  174. logging.info('头版多图选择 结束')
  175. def movie_set():
  176. file_name = os.path.basename(info_v)
  177. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/div[1]/div/div[3]/div/div').click()
  178. self.driver.find_element_by_xpath('//*[@class="comptEditButton-2JsnAFdOGZ"]').click()
  179. WebDriverWait(self.driver, 100).until(
  180. lambda x: len([_ for _ in self.driver.find_elements_by_class_name('title-29sncpKgTl') if
  181. _.is_displayed() and _.is_enabled()]) > 0)
  182. #
  183. turn_page_buttons = self.driver.find_elements_by_class_name('paginationIcon-1EfoH0sNRF')
  184. can_use_button = []
  185. for _ in turn_page_buttons:
  186. if _.is_enabled() and _.is_displayed():
  187. can_use_button.append(_)
  188. # 不断翻页获取到元素为止
  189. chose_over = False
  190. while True:
  191. page_elements = self.driver.find_elements_by_class_name('title-29sncpKgTl')
  192. for _ in page_elements:
  193. if _.is_displayed() and _.is_enabled():
  194. if file_name in _.text:
  195. _.click()
  196. chose_over = True
  197. break
  198. if chose_over or len(can_use_button) == 0:
  199. # can_use_button 数量说明是否可以翻页,如果不可以翻页,则直接停止
  200. break
  201. # 翻到最后一页时停止
  202. page_text_elements = self.driver.find_elements_by_class_name('count_small-37CcvfzoTl')
  203. for _ in page_text_elements:
  204. if _.is_enabled() and _.is_displayed():
  205. page_text = _.text
  206. page_text_element = _
  207. page_nums = re.findall('\d+', page_text)
  208. if int(page_nums[0].strip()) == int(page_nums[1].strip()):
  209. break
  210. # 翻页
  211. can_use_button[2].click()
  212. # 确保翻页成功
  213. WebDriverWait(self.driver, 10).until(
  214. lambda x: page_text != page_text_element.text)
  215. sc_buttons = self.driver.find_elements_by_id('test_material_container_confirm')
  216. for _ in sc_buttons:
  217. if _.is_enabled() and _.is_displayed():
  218. _.click()
  219. info_key = list(info.keys())[0]
  220. info_v = info[info_key]
  221. if info_key == 'page':
  222. single_page_set()
  223. if info_key == 'multi_page':
  224. multi_page_set()
  225. if info_key == 'movie':
  226. movie_set()
  227. # 设置头部组件
  228. pass
  229. def set_page(self, page_path):
  230. # 设置图片模块
  231. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/section/div[2]/div[1]/div/div').click()
  232. time.sleep(random.uniform(0.1, 0.2))
  233. file_name = os.path.basename(page_path)
  234. upload_elements = self.driver.find_elements_by_class_name('upload-img-item-inner-2gsg7NjaZ8')
  235. for _ in upload_elements:
  236. if _.is_displayed() and _.is_enabled():
  237. _.click()
  238. WebDriverWait(self.driver, 10).until(
  239. lambda x: len([_ for _ in self.driver.find_elements_by_class_name('title-29sncpKgTl') if
  240. _.is_displayed() and _.is_enabled()]) > 0)
  241. turn_page_buttons = self.driver.find_elements_by_class_name('paginationIcon-1EfoH0sNRF')
  242. can_use_button = []
  243. for _ in turn_page_buttons:
  244. if _.is_enabled() and _.is_displayed():
  245. can_use_button.append(_)
  246. # 不断翻页获取到元素为止
  247. chose_over = False
  248. while True:
  249. page_elements = self.driver.find_elements_by_class_name('title-29sncpKgTl')
  250. for _ in page_elements:
  251. if _.is_displayed() and _.is_enabled():
  252. if file_name in _.text:
  253. _.click()
  254. chose_over = True
  255. break
  256. if chose_over or len(can_use_button) == 0:
  257. # can_use_button 数量说明是否可以翻页,如果不可以翻页,则直接停止
  258. break
  259. # 翻到最后一页时停止
  260. page_text_elements = self.driver.find_elements_by_class_name('count_small-37CcvfzoTl')
  261. for _ in page_text_elements:
  262. if _.is_enabled() and _.is_displayed():
  263. page_text = _.text
  264. page_text_element = _
  265. page_nums = re.findall('\d+', page_text)
  266. if int(page_nums[0].strip()) == int(page_nums[1].strip()):
  267. break
  268. # 翻页
  269. can_use_button[2].click()
  270. # 确保翻页成功
  271. WebDriverWait(self.driver, 10).until(
  272. lambda x: page_text != page_text_element.text)
  273. sc_buttons = self.driver.find_elements_by_id('test_material_container_confirm')
  274. for _ in sc_buttons:
  275. if _.is_enabled() and _.is_displayed():
  276. _.click()
  277. try:
  278. WebDriverWait(self.driver, 4).until(
  279. lambda driver: driver.find_element_by_class_name(
  280. 'btnFist-uueBS6DQFa'))
  281. _ = self.driver.find_element_by_class_name(
  282. 'btnFist-uueBS6DQFa')
  283. WebDriverWait(self.driver, 4).until(
  284. lambda x: (_.is_displayed() and _.is_enabled()))
  285. # 已经出现但任需要等待
  286. time.sleep(1)
  287. _.click()
  288. WebDriverWait(self.driver, 100).until(
  289. lambda x: len([_ for _ in self.driver.find_elements_by_class_name('btn-3E823IXt3m') if
  290. _.is_displayed() and _.is_enabled()]) > 0)
  291. for _ in self.driver.find_elements_by_class_name('btn-3E823IXt3m'):
  292. if _.is_displayed() and _.is_enabled():
  293. _.click()
  294. except Exception as e:
  295. logging.info(e)
  296. logging.info('图片模块设置结束')
  297. def set_content(self, config_info):
  298. # 设置文本模块
  299. # 1.文本内容2.文本颜色3.是否加粗4.文本位置设置5.文本大小
  300. # 设置文本内容
  301. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/section/div[2]/div[5]/div/div').click()
  302. time.sleep(random.uniform(0.2, 0.3))
  303. input_elements = self.driver.find_elements_by_xpath('//textarea[@class="adui-input-base"]')
  304. for _ in input_elements:
  305. if _.is_enabled() and _.is_displayed():
  306. _.send_keys(config_info['content'])
  307. # 设置颜色
  308. if config_info['color'] != '595959':
  309. color_buttons = self.driver.find_elements_by_class_name('adui-cp-picker')
  310. c_buttons_can_use = []
  311. for _ in color_buttons:
  312. if _.is_displayed() and _.is_enabled():
  313. c_buttons_can_use.append(_)
  314. c_buttons_can_use[1].click()
  315. time.sleep(random.uniform(0.2, 0.3))
  316. input_elements = self.driver.find_elements_by_tag_name('input')
  317. for _ in input_elements:
  318. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '595959':
  319. _.click()
  320. _.send_keys(config_info['color'])
  321. # 设置是否加粗
  322. if config_info['is_bold']:
  323. big_elements = self.driver.find_elements_by_class_name('adui-button-content')
  324. for _ in big_elements:
  325. if _.text == '加粗' and _.is_displayed() and _.is_enabled():
  326. _.click()
  327. # 设置文本位置
  328. if config_info['loc'] != 'left':
  329. loc_buttons = self.driver.find_elements_by_xpath(
  330. "//div[contains(@class, 'adui-button-group_banner')]//button")
  331. loc_buttons_can_use = []
  332. for _ in loc_buttons:
  333. if _.is_enabled() and _.is_displayed():
  334. loc_buttons_can_use.append(_)
  335. if config_info['loc'] == 'middle':
  336. loc_buttons_can_use[1].click()
  337. if config_info['loc'] == 'right':
  338. loc_buttons_can_use[2].click()
  339. # 设置文本大小
  340. if config_info['str_num'] != 15:
  341. str_buttons = self.driver.find_elements_by_xpath("//*[@class='adui-select-selection__rendered']")
  342. str_buttons_can_use = []
  343. for _ in str_buttons:
  344. if _.is_displayed() and _.is_enabled():
  345. str_buttons_can_use.append(_)
  346. str_buttons_can_use[1].click()
  347. time.sleep(random.uniform(0.5, 1))
  348. str_num_buttons = self.driver.find_elements_by_xpath("//*[@class='adui-select-dropdown-menu-item']")
  349. str_num_can_use = []
  350. for _ in str_num_buttons:
  351. if _.is_displayed() and _.is_enabled():
  352. str_num_can_use.append(_)
  353. str_num_map = {14: 0, 16: 1, 18: 2, 20: 3, 24: 4, 36: 5}
  354. str_num_can_use[str_num_map[config_info['str_num']]].click()
  355. # 设置文本边距
  356. if config_info['str_distance'][0] != 22 or config_info['str_distance'][1] != 22:
  357. distance_buttons = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  358. distance_buttons_can_use = []
  359. for _ in distance_buttons:
  360. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '22':
  361. distance_buttons_can_use.append(_)
  362. distance_buttons_can_use[0].click()
  363. for i in range(4):
  364. distance_buttons_can_use[0].send_keys(Keys.BACKSPACE)
  365. distance_buttons_can_use[0].send_keys(config_info['str_distance'][0])
  366. distance_buttons_can_use[1].click()
  367. for i in range(4):
  368. distance_buttons_can_use[1].send_keys(Keys.BACKSPACE)
  369. distance_buttons_can_use[1].send_keys(config_info['str_distance'][1])
  370. def set_follow_button(self, button_type):
  371. # 设置关注按钮
  372. # 1.设置button文本内容2.是否加粗3.设置字体颜色,边框颜色,填充色4.设置边距
  373. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/section/div[4]/div[2]/div/div').click()
  374. if button_type == 1:
  375. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  376. for _ in input_elements:
  377. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '关注公众号':
  378. _.click()
  379. _.clear()
  380. for i in range(10):
  381. _.send_keys(Keys.BACKSPACE)
  382. _.send_keys('保存阅读记录')
  383. big_elements = self.driver.find_elements_by_xpath('//span[@class="adui-button-content"]')
  384. for _ in big_elements:
  385. if _.text == '加粗' and _.is_displayed() and _.is_enabled():
  386. _.click()
  387. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  388. for _ in input_elements:
  389. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '07C160':
  390. _.click()
  391. _.send_keys('DE2821')
  392. if button_type == 2:
  393. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  394. for _ in input_elements:
  395. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '关注公众号':
  396. _.click()
  397. _.clear()
  398. for i in range(10):
  399. _.send_keys(Keys.BACKSPACE)
  400. _.send_keys('点击此处,继续阅读')
  401. big_elements = self.driver.find_elements_by_xpath('//span[@class="adui-button-content"]')
  402. for _ in big_elements:
  403. if _.text == '加粗' and _.is_displayed() and _.is_enabled():
  404. _.click()
  405. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  406. for _ in input_elements:
  407. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '07C160':
  408. _.click()
  409. _.send_keys('DE2821')
  410. size_buttons = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  411. size_buttons_can_use = []
  412. for _ in size_buttons:
  413. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '28':
  414. size_buttons_can_use.append(_)
  415. size_buttons_can_use[0].click()
  416. for i in range(4):
  417. size_buttons_can_use[0].send_keys(Keys.BACKSPACE)
  418. size_buttons_can_use[0].send_keys('0')
  419. size_buttons_can_use[1].click()
  420. for i in range(4):
  421. size_buttons_can_use[1].send_keys(Keys.BACKSPACE)
  422. size_buttons_can_use[1].send_keys('0')
  423. if button_type == 3:
  424. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  425. for _ in input_elements:
  426. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '关注公众号':
  427. _.click()
  428. _.clear()
  429. for i in range(10):
  430. _.send_keys(Keys.BACKSPACE)
  431. _.send_keys('点我,继续阅读')
  432. big_elements = self.driver.find_elements_by_xpath('//span[@class="adui-button-content"]')
  433. for _ in big_elements:
  434. if _.text == '加粗' and _.is_displayed() and _.is_enabled():
  435. _.click()
  436. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  437. for _ in input_elements:
  438. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '07C160':
  439. _.click()
  440. _.send_keys('FFFFFF')
  441. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  442. for _ in input_elements:
  443. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == 'FFFFFF':
  444. _.click()
  445. _.send_keys('DE2821')
  446. break
  447. size_buttons = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  448. size_buttons_can_use = []
  449. for _ in size_buttons:
  450. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '28':
  451. size_buttons_can_use.append(_)
  452. size_buttons_can_use[0].click()
  453. for i in range(4):
  454. size_buttons_can_use[0].send_keys(Keys.BACKSPACE)
  455. size_buttons_can_use[0].send_keys('0')
  456. size_buttons_can_use[1].click()
  457. for i in range(4):
  458. size_buttons_can_use[1].send_keys(Keys.BACKSPACE)
  459. size_buttons_can_use[1].send_keys('100')
  460. def set_follow_button_(self, config_info):
  461. # 设置关注按钮
  462. # 1.设置button文本内容 2.是否加粗 3.设置字体颜色,边框颜色,填充色 4.设置边距
  463. self.driver.find_element_by_xpath('//*[@id="stage-sidebar"]/section/div[4]/div[2]/div/div').click()
  464. # 文本设置
  465. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  466. for _ in input_elements:
  467. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '关注公众号':
  468. _.click()
  469. _.clear()
  470. for i in range(10):
  471. _.send_keys(Keys.BACKSPACE)
  472. _.send_keys(config_info['content'])
  473. # 文本是否加粗
  474. if config_info['is_bold']:
  475. big_elements = self.driver.find_elements_by_xpath('//span[@class="adui-button-content"]')
  476. for _ in big_elements:
  477. if _.text == '加粗' and _.is_displayed() and _.is_enabled():
  478. _.click()
  479. # 颜色设置
  480. input_elements = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  481. input_elements_can_use = []
  482. for _ in input_elements:
  483. if _.is_enabled() and _.is_displayed() and (
  484. _.get_attribute("value") == '07C160' or _.get_attribute("value") == 'FFFFFF'):
  485. input_elements_can_use.append(_)
  486. input_elements_can_use[0].click()
  487. input_elements_can_use[0].send_keys(config_info['color1'])
  488. time.sleep(random.uniform(0.1, 0.5))
  489. input_elements_can_use[1].click()
  490. input_elements_can_use[1].send_keys(config_info['color2'])
  491. time.sleep(random.uniform(0.1, 0.5))
  492. input_elements_can_use[2].click()
  493. input_elements_can_use[2].send_keys(config_info['color3'])
  494. time.sleep(random.uniform(0.1, 0.5))
  495. # 间隙设置
  496. size_buttons = self.driver.find_elements_by_xpath('//input[@class="adui-input-base"]')
  497. size_buttons_can_use = []
  498. for _ in size_buttons:
  499. if _.is_enabled() and _.is_displayed() and _.get_attribute("value") == '28':
  500. size_buttons_can_use.append(_)
  501. size_buttons_can_use[0].click()
  502. for i in range(4):
  503. size_buttons_can_use[0].send_keys(Keys.BACKSPACE)
  504. size_buttons_can_use[0].send_keys(config_info['str_distance'][0])
  505. size_buttons_can_use[1].click()
  506. for i in range(4):
  507. size_buttons_can_use[1].send_keys(Keys.BACKSPACE)
  508. size_buttons_can_use[1].send_keys(config_info['str_distance'][1])
  509. def set_text_button(self):
  510. # 设置图文按钮
  511. pass
  512. def send_file_multi(self, layout, err_num=0):
  513. # 有问题,暂时不使用
  514. # 上传文件,文件上传与整体流程切割开
  515. token = re.findall('token=(\d+)', self.driver.current_url)
  516. url_ = 'https://mp.weixin.qq.com/promotion/frame?t=ad_system/common_frame&t1=material_std/material_library&token={}'.format(
  517. token[0])
  518. js = "window.open('{}')".format(url_)
  519. self.driver.execute_script(js)
  520. time.sleep(random.uniform(1, 2))
  521. self.driver.switch_to.window(self.driver.window_handles[-1])
  522. file_set = set()
  523. for v in layout.values():
  524. if isinstance(v, dict):
  525. if 'multi_page' in v.keys() or 'page' in v.keys() or 'movie' in v.keys():
  526. v_name = list(v.keys())[0]
  527. if isinstance(v[v_name], list):
  528. for _ in v[v_name]:
  529. file_set.add(_)
  530. else:
  531. file_set.add(v[v_name])
  532. file_list = list(file_set)
  533. # print(file_list)
  534. # print('file list size', len(file_list))
  535. send_file_sign = self.send_file_limit_num
  536. for _ in file_list:
  537. # print(_)
  538. self.driver.find_element_by_xpath('//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/input').send_keys(_)
  539. time.sleep(100)
  540. while True:
  541. # 失败,失败直接退出重跑
  542. # 正在上传数量,如果是正在上传小于限定数量,就不断输入
  543. # 上传完毕,小于限定数量,不断输入,.....已经上传好了,就关闭
  544. time.sleep(1)
  545. send_reslut_content = self.driver.find_element_by_xpath(
  546. '//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/div/strong').text
  547. if '失败' in send_reslut_content:
  548. if err_num < 3:
  549. self.send_file(layout, err_num=err_num + 1)
  550. else:
  551. exit()
  552. if '正在上传' in send_reslut_content:
  553. if send_file_sign < len(file_list):
  554. send_num = re.findall('(\d+)', send_reslut_content)[0]
  555. if int(send_num) < self.send_file_limit_num:
  556. # 还可以继续上传
  557. x = send_file_sign
  558. can_send_sign = send_file_sign + (self.send_file_limit_num - send_num)
  559. y = can_send_sign if can_send_sign < len(file_list) else len(file_list)
  560. for i in range(x, y):
  561. send_file_sign = send_file_sign + 1
  562. self.driver.find_element_by_xpath(
  563. '//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/input').send_keys(file_list[i])
  564. else:
  565. pass
  566. if '上传成功' in send_reslut_content:
  567. if send_file_sign < len(file_list):
  568. send_num = re.findall('(\d+)', send_reslut_content)[0]
  569. if int(send_num) < self.send_file_limit_num:
  570. # 还可以继续上传
  571. x = send_file_sign
  572. can_send_sign = send_file_sign + (self.send_file_limit_num - send_num)
  573. y = can_send_sign if can_send_sign < len(file_list) else len(file_list)
  574. for i in range(x, y):
  575. send_file_sign = send_file_sign + 1
  576. self.driver.find_element_by_xpath(
  577. '//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/input').send_keys(file_list[i])
  578. else:
  579. break
  580. time.sleep(1000)
  581. self.driver.execute_script('window.close();')
  582. def send_file(self, file_path, err_num=0):
  583. # 有问题,暂时不使用
  584. self.driver.execute_script('location.reload();')
  585. self.driver.find_element_by_xpath('//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/input').send_keys(file_path)
  586. def send_file_alone(self, layout):
  587. # 上传文件,单线程
  588. # 上传文件,文件上传与整体流程切割开
  589. token = re.findall('token=(\d+)', self.driver.current_url)
  590. url_ = 'https://mp.weixin.qq.com/promotion/frame?t=ad_system/common_frame&t1=material_std/material_library&token={}'.format(
  591. token[0])
  592. js = "window.open('{}')".format(url_)
  593. self.driver.execute_script(js)
  594. time.sleep(random.uniform(1, 2))
  595. self.driver.switch_to.window(self.driver.window_handles[-1])
  596. file_set = set()
  597. for v in layout.values():
  598. if isinstance(v, dict):
  599. if 'multi_page' in v.keys() or 'page' in v.keys() or 'movie' in v.keys():
  600. v_name = list(v.keys())[0]
  601. if isinstance(v[v_name], list):
  602. for _ in v[v_name]:
  603. file_set.add(_)
  604. else:
  605. file_set.add(v[v_name])
  606. for _ in file_set:
  607. self.send_file(_)
  608. err_num = 0
  609. while True:
  610. time.sleep(1)
  611. send_reslut_content = self.driver.find_element_by_xpath(
  612. '//*[@id="wxadcontainer"]/div[1]/div[2]/div[4]/div/strong').text
  613. if '上传成功' in send_reslut_content:
  614. break
  615. if '失败' in send_reslut_content:
  616. err_num = err_num + 1
  617. self.send_file(_)
  618. if err_num > 3:
  619. raise ValueError("图片上传失败")
  620. self.driver.execute_script('window.close();')
  621. self.driver.switch_to.window(self.driver.window_handles[-1])
  622. def set_share_content(self, share_info):
  623. title_content = share_info['share_info']['title']
  624. des_content = share_info['share_info']['des']
  625. self.driver.find_element_by_xpath('//*[@id="wxadcontainer"]/div[1]/div/section/header/div[2]/button[2]').click()
  626. WebDriverWait(self.driver, 50).until(lambda driver: driver.find_element_by_xpath(
  627. '//*[@id="wxadcontainer"]/div[1]/div/div/div/div[1]/section/section/div[2]/div[1]/div/div/input'))
  628. title_input = self.driver.find_element_by_xpath(
  629. '//*[@id="wxadcontainer"]/div[1]/div/div/div/div[1]/section/section/div[2]/div[1]/div/div/input')
  630. title_input.click()
  631. title_input.send_keys(title_content)
  632. des_input = self.driver.find_element_by_xpath(
  633. '//*[@id="wxadcontainer"]/div[1]/div/div/div/div[1]/section/section/div[2]/div[2]/div/div/input')
  634. des_input.click()
  635. des_input.send_keys(des_content)
  636. self.driver.find_element_by_xpath('//*[@id="wxadcontainer"]/div[1]/div/header/div[2]/button').click()
  637. WebDriverWait(self.driver, 10).until(
  638. lambda driver: driver.find_element_by_xpath('/html/body/div[6]/div/div/div[2]/div/div[3]/button[2]'))
  639. self.driver.find_element_by_xpath('/html/body/div[6]/div/div/div[2]/div/div[3]/button[2]').click()
  640. time.sleep(1)
  641. def create_layout(self, layout, err_num=0):
  642. #
  643. try:
  644. self.send_file_alone(layout)
  645. advertisement_sign = self.set_advertisement_sign()
  646. self.set_head_assemb(layout[-1])
  647. if -2 in layout.keys():
  648. self.set_background_color()
  649. for _ in range(max(layout.keys()) + 1):
  650. info = layout[_]
  651. info_key = list(info.keys())[0]
  652. info_v = info[info_key]
  653. if info_key == 'page':
  654. self.set_page(info_v)
  655. if info_key == 'content':
  656. self.set_content(info_v)
  657. if info_key == 'follow_button':
  658. self.set_follow_button_(info_v)
  659. self.set_share_content(layout[-3])
  660. self.driver.execute_script('window.close();')
  661. # 切回到前一页
  662. self.driver.switch_to.window(self.driver.window_handles[-1])
  663. layout_info = {}
  664. layout_info['id'] = int(time.time() * 1000)
  665. layout_info['userid'] = self.user_id
  666. layout_info['result'] = 'sucess'
  667. layout_info['layout'] = json.dumps(layout, ensure_ascii=False)
  668. layout_insert = save_ad_layout_result(layout_info=layout_info, table_layout=self.layout_table)
  669. self.sql_session.execute(layout_insert)
  670. self.sql_session.commit()
  671. return {'sucess': True, 'result_info': advertisement_sign}
  672. except Exception as e:
  673. #TODO:有空时讲 e 内容设置为原始内容
  674. if err_num > 3:
  675. layout_num = int(time.time() * 1000)
  676. now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  677. try:
  678. self.driver.save_screenshot('{layout_num}-{now_time}-{service_name}-{wechat_name}.png'.format(
  679. layout_num=layout_num,
  680. now_time=now_time,
  681. service_name=self.service_name,
  682. wechat_name=self.wechat_name))
  683. except:
  684. pass
  685. layout_info = {}
  686. layout_info['id'] = layout_num
  687. layout_info['userid'] = self.user_id
  688. layout_info['result'] = str(e)
  689. layout_info['layout'] = json.dumps(layout)
  690. layout_insert = save_ad_layout_result(layout_info=layout_info, table_layout=self.layout_table)
  691. self.sql_session.execute(layout_insert)
  692. self.sql_session.commit()
  693. # 截图,传回错误信息
  694. return {'sucess': False, 'result_info': e}
  695. else:
  696. self.create_layout(layout, err_num=err_num + 1)
  697. if __name__ == '__main__':
  698. logging.basicConfig(
  699. handlers=[
  700. logging.handlers.RotatingFileHandler('./create_ad.log',
  701. maxBytes=10 * 1024 * 1024,
  702. backupCount=5,
  703. encoding='utf-8')
  704. , logging.StreamHandler() # 供输出使用
  705. ],
  706. level=logging.INFO,
  707. format="%(asctime)s - %(levelname)s %(filename)s %(funcName)s %(lineno)s - %(message)s"
  708. )