create_ad.py 32 KB

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