create_ad_layout.py 35 KB

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