douyin_train_home_comment.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. import random
  2. import time
  3. from func.action_func import del_key_vague
  4. from task.task_job import callback_task
  5. from tools import loggerKit, redis_client
  6. from scene.oprator.atom_data import start_app, stop_app, continual_swipe_screen, single_click_by_control, swipe_screen, \
  7. get_text_by_control
  8. import yaml
  9. with open('config.yaml', 'r') as file:
  10. config = yaml.load(file, Loader=yaml.FullLoader)
  11. extern_domain = config['bmp-cp']['extern_domain']
  12. # 任务执行回调url
  13. task_callback_url = extern_domain + config['bmp-cp']['task_callback_url']
  14. # 抖音养号首页帖子评论(浏览30-50帖子 随机时长 对其评论进行观看)
  15. # version 29.5.0
  16. def douyin_spider(task_id, keyword, data):
  17. loggerKit.info('请求信息:{0}'.format(data))
  18. device_id = data.get("deviceID")
  19. perform_action_id = data.get("performActionId")
  20. result = data.get("result")
  21. if result is not None:
  22. """
  23. 非首个指令
  24. """
  25. perform_action_result = result.get("performActionResult")
  26. if perform_action_result is None:
  27. return_dict = {
  28. "data": "",
  29. "code": -2,
  30. "message": "fail, performActionResult is null"
  31. }
  32. # 回调任务中心
  33. del_key_vague(device_id)
  34. callback_task(500, '指令执行失败', task_id, device_id, 0, None)
  35. return return_dict
  36. if perform_action_result == "failure":
  37. # 回调任务中心
  38. return_dict = {
  39. "data": "",
  40. "code": -2,
  41. "message": "fail, performActionResult is not success"
  42. }
  43. del_key_vague(device_id)
  44. callback_task(500, '任务执行失败', task_id, device_id, 0, None)
  45. return return_dict
  46. if perform_action_result == "stop":
  47. # 回调任务中心
  48. return_dict = {
  49. "data": "",
  50. "code": -2,
  51. "message": "fail, performActionResult is not success"
  52. }
  53. del_key_vague(device_id)
  54. callback_task(500, '指令被用户终止', task_id, device_id, 0, None)
  55. return return_dict
  56. # 每次操作完成后会将对应的操作唯一id存储到redis,并且返回给手机端 手机端下次带着上个操作id来执行下一个操作
  57. last_action_id = redis_client.get(device_id + "operate")
  58. step0 = redis_client.get(f"{device_id}_step0")
  59. if step0 is not None and int(step0) == 1 and last_action_id is not None and int(perform_action_id) == int(
  60. last_action_id):
  61. action1_id = int(round(time.time() * 1000))
  62. """
  63. 发送第1条指令
  64. 滑动15-20个视频
  65. """
  66. swipe_count = random.randint(5, 10)
  67. action1_dict = continual_swipe_screen(action1_id,
  68. package_name="com.ss.android.ugc.aweme.lite",
  69. continuous_time_interval='3,10',
  70. continuous_count=swipe_count)
  71. redis_client.set(device_id + "operate", action1_id)
  72. redis_client.set(f"{device_id}_step1", "1")
  73. redis_client.delete(f"{device_id}_step0")
  74. loggerKit.info("任务:{0}, action1_id,滑动15-20个视频", task_id)
  75. return action1_dict
  76. step1 = redis_client.get(f"{device_id}_step1")
  77. # 获取评论数量
  78. if step1 is not None and int(step1) == 1 and last_action_id is not None and int(perform_action_id) == int(
  79. last_action_id):
  80. loggerKit.info("设备:{0}, action1_id_mem:{1}", device_id, int(last_action_id))
  81. action2_id = int(round(time.time() * 1000))
  82. """
  83. 发送第2条指令
  84. 获取评论数量
  85. """
  86. action2_dict = get_text_by_control(action2_id, target_app="douyin", target_version="28.8.0",
  87. package_name="com.ss.android.ugc.aweme.lite",
  88. max_page='1',
  89. control_id="com.ss.android.ugc.aweme.lite:id/bez", timeout=5,
  90. item_index=0)
  91. redis_client.set(device_id + "operate", action2_id)
  92. redis_client.set(f"{device_id}_step2", "1")
  93. redis_client.delete(f"{device_id}_step1")
  94. loggerKit.info("任务:{0}, action2_id,获取评论数量", task_id)
  95. return action2_dict
  96. step2 = redis_client.get(f"{device_id}_step2")
  97. # 判断是否有评论数
  98. if step2 is not None and int(step2) == 1 and last_action_id is not None and int(perform_action_id) == int(
  99. last_action_id):
  100. loggerKit.info("设备:{0}, action1_id_mem:{1}", device_id, int(last_action_id))
  101. action3_id = int(round(time.time() * 1000))
  102. """
  103. 发送第3条指令
  104. 判断是否有评论数量
  105. """
  106. result_text = result.get("performActionText")
  107. if result_text is None or result_text == '':
  108. # 没有获取到评论数量,可能是在直播间页面。跳过此次点开评论操作
  109. # 向下滑动一次,再重新获取评论
  110. action2_dict = swipe_screen(action3_id,
  111. package_name="com.ss.android.ugc.aweme.lite",
  112. sleep_time=3)
  113. redis_client.set(device_id + "operate", action3_id)
  114. redis_client.delete(f"{device_id}_step2")
  115. redis_client.set(f"{device_id}_step1", "1")
  116. loggerKit.info("任务:{0}, action3_id,评论信息为:{1},不可点击再次滑动", task_id, result_text)
  117. return action2_dict
  118. elif result_text == '评论':
  119. # 没有对应的评论次数,仅有评论文案 证明该帖子无评论。跳过此次点开评论操作
  120. # 向下滑动一次,再重新获取评论
  121. action2_dict = swipe_screen(action3_id,
  122. package_name="com.ss.android.ugc.aweme.lite",
  123. sleep_time=3)
  124. redis_client.set(device_id + "operate", action3_id)
  125. redis_client.delete(f"{device_id}_step2")
  126. redis_client.set(f"{device_id}_step1", "1")
  127. loggerKit.info("任务:{0}, action3_id,评论信息为:{1},不可点击再次滑动", task_id, result_text)
  128. return action2_dict
  129. else:
  130. # 有对应评论,需要点击进去进行滑动
  131. action3_dict = single_click_by_control(action3_id, target_app="douyin", target_version="28.8.0",
  132. package_name="com.ss.android.ugc.aweme.lite",
  133. control_id="com.ss.android.ugc.aweme.lite:id/comment_container",
  134. timeout=5)
  135. redis_client.set(device_id + "operate", action3_id)
  136. redis_client.set(f"{device_id}_step3", "1")
  137. redis_client.delete(f"{device_id}_step2")
  138. loggerKit.info("任务:{0}, action3_id,评论信息为:{1},点击评论框", task_id, result_text)
  139. return action3_dict
  140. # 进行滑动
  141. step3 = redis_client.get(f"{device_id}_step3")
  142. if step3 is not None and int(step3) == 1 and last_action_id is not None and int(perform_action_id) == int(
  143. last_action_id):
  144. loggerKit.info("设备:{0}, action3_id_mem:{1}", device_id, int(last_action_id))
  145. action4_id = int(round(time.time() * 1000))
  146. """
  147. 发送第4条指令
  148. 进行滑动
  149. """
  150. action4_dict = swipe_screen(action4_id,
  151. package_name="com.ss.android.ugc.aweme.lite",
  152. sleep_time=8)
  153. redis_client.set(device_id + "operate", action4_id)
  154. redis_client.set(f"{device_id}_step4", "1")
  155. redis_client.delete(f"{device_id}_step3")
  156. loggerKit.info("任务:{0}, action4_id,向上滑动一次", task_id)
  157. return action4_dict
  158. # 关闭评论框
  159. step4 = redis_client.get(f"{device_id}_step4")
  160. if step4 is not None and int(step4) == 1 and last_action_id is not None and int(perform_action_id) == int(
  161. last_action_id):
  162. loggerKit.info("设备:{0}, action4_id_mem:{1}", device_id, int(last_action_id))
  163. action5_id = int(round(time.time() * 1000))
  164. """
  165. 发送第4条指令
  166. 关闭评论框
  167. """
  168. action5_dict = single_click_by_control(action5_id, target_app="douyin", target_version="28.8.0",
  169. package_name="com.ss.android.ugc.aweme.lite",
  170. control_id="com.ss.android.ugc.aweme.lite:id/back_btn",
  171. control_ids="com.ss.android.ugc.aweme.lite:id/back_btn,"
  172. "com.ss.android.ugc.aweme.lite:id/back",
  173. timeout=5)
  174. redis_client.set(device_id + "operate", action5_id)
  175. redis_client.set(f"{device_id}_step5", "1")
  176. redis_client.delete(f"{device_id}_step4")
  177. loggerKit.info("任务:{0}, action5_id,关闭评论", task_id)
  178. return action5_dict
  179. step5 = redis_client.get(f"{device_id}_step5")
  180. if step5 is not None and int(step5) == 1 and last_action_id is not None and int(perform_action_id) == int(
  181. last_action_id):
  182. action6_id = int(round(time.time() * 1000))
  183. """
  184. 发送第6条指令
  185. 滑动10-15个视频
  186. """
  187. if perform_action_result == "invalid operation":
  188. # 回调任务中心
  189. return_dict = {
  190. "data": "",
  191. "code": -2,
  192. "message": "fail, performActionResult is not success"
  193. }
  194. del_key_vague(device_id)
  195. callback_task(500, '任务执行失败,无法正常关闭评论框', task_id, device_id, 0, None)
  196. return return_dict
  197. swipe_count = random.randint(5, 10)
  198. action6_dict = continual_swipe_screen(action6_id,
  199. package_name="com.ss.android.ugc.aweme.lite",
  200. continuous_time_interval='3,10',
  201. continuous_count=swipe_count)
  202. redis_client.set(device_id + "operate", action6_id)
  203. redis_client.set(f"{device_id}_step6", "1")
  204. redis_client.delete(f"{device_id}_step5")
  205. loggerKit.info("任务:{0}, action6_id,继续下滑10-15个视频", task_id)
  206. return action6_dict
  207. step6 = redis_client.get(f"{device_id}_step6")
  208. # 获取评论数量
  209. if step6 is not None and int(step6) == 1 and last_action_id is not None and int(perform_action_id) == int(
  210. last_action_id):
  211. loggerKit.info("设备:{0}, action6_id_mem:{1}", device_id, int(last_action_id))
  212. action7_id = int(round(time.time() * 1000))
  213. """
  214. 发送第7条指令
  215. 获取评论数量
  216. """
  217. action7_dict = get_text_by_control(action7_id, target_app="douyin", target_version="28.8.0",
  218. package_name="com.ss.android.ugc.aweme.lite",
  219. max_page='1',
  220. control_id="com.ss.android.ugc.aweme.lite:id/bez", timeout=5,
  221. item_index=0)
  222. redis_client.set(device_id + "operate", action7_id)
  223. redis_client.set(f"{device_id}_step7", "1")
  224. redis_client.delete(f"{device_id}_step6")
  225. loggerKit.info("任务:{0}, action7_id,获取评论数量", task_id)
  226. return action7_dict
  227. step7 = redis_client.get(f"{device_id}_step7")
  228. # 判断是否有评论数
  229. if step7 is not None and int(step7) == 1 and last_action_id is not None and int(perform_action_id) == int(
  230. last_action_id):
  231. loggerKit.info("设备:{0}, action1_id_mem:{1}", device_id, int(last_action_id))
  232. action8_id = int(round(time.time() * 1000))
  233. """
  234. 发送第3条指令
  235. 判断是否有评论数量
  236. """
  237. result_text = result.get("performActionText")
  238. if result_text is None or result_text == '':
  239. # 没有获取到评论数量,可能是在直播间页面。跳过此次点开评论操作
  240. # 向下滑动一次,再重新获取评论
  241. action8_dict = swipe_screen(action8_id,
  242. package_name="com.ss.android.ugc.aweme.lite",
  243. sleep_time=3)
  244. redis_client.set(device_id + "operate", action8_id)
  245. redis_client.delete(f"{device_id}_step7")
  246. redis_client.set(f"{device_id}_step6", "1")
  247. loggerKit.info("任务:{0}, action8_id,获取评论数量为:{1},继续向下滑动", task_id, result_text)
  248. return action8_dict
  249. elif result_text == '评论':
  250. # 没有对应的评论次数,仅有评论文案 证明该帖子无评论。跳过此次点开评论操作
  251. # 向下滑动一次,再重新获取评论
  252. action8_dict = swipe_screen(action8_id,
  253. package_name="com.ss.android.ugc.aweme.lite",
  254. sleep_time=3)
  255. redis_client.set(device_id + "operate", action8_id)
  256. redis_client.delete(f"{device_id}_step7")
  257. redis_client.set(f"{device_id}_step6", "1")
  258. loggerKit.info("任务:{0}, action8_id,获取评论数量为:{1},继续向下滑动", task_id, result_text)
  259. return action8_dict
  260. else:
  261. # 有对应评论,需要点击进去进行滑动
  262. action8_dict = single_click_by_control(action8_id, target_app="douyin", target_version="28.8.0",
  263. package_name="com.ss.android.ugc.aweme.lite",
  264. control_id="com.ss.android.ugc.aweme.lite:id/comment_container",
  265. timeout=5)
  266. redis_client.set(device_id + "operate", action8_id)
  267. redis_client.set(f"{device_id}_step8", "1")
  268. redis_client.delete(f"{device_id}_step7")
  269. loggerKit.info("任务:{0}, action8_id,获取评论数量为:{1},点开评论", task_id, result_text)
  270. return action8_dict
  271. # 进行滑动
  272. step8 = redis_client.get(f"{device_id}_step8")
  273. if step8 is not None and int(step8) == 1 and last_action_id is not None and int(perform_action_id) == int(
  274. last_action_id):
  275. loggerKit.info("设备:{0}, action8_id_mem:{1}", device_id, int(last_action_id))
  276. action9_id = int(round(time.time() * 1000))
  277. """
  278. 发送第9条指令
  279. 进行滑动
  280. """
  281. action9_dict = swipe_screen(action9_id,
  282. package_name="com.ss.android.ugc.aweme.lite",
  283. sleep_time=8)
  284. redis_client.set(device_id + "operate", action9_id)
  285. redis_client.set(f"{device_id}_step9", "1")
  286. redis_client.delete(f"{device_id}_step8")
  287. loggerKit.info("任务:{0}, action9_id,滑动评论", task_id)
  288. return action9_dict
  289. # 关闭评论框
  290. step9 = redis_client.get(f"{device_id}_step9")
  291. if step9 is not None and int(step9) == 1 and last_action_id is not None and int(perform_action_id) == int(
  292. last_action_id):
  293. loggerKit.info("设备:{0}, action9_id_mem:{1}", device_id, int(last_action_id))
  294. if perform_action_result == "invalid operation":
  295. # 回调任务中心
  296. return_dict = {
  297. "data": "",
  298. "code": -2,
  299. "message": "fail, performActionResult is not success"
  300. }
  301. del_key_vague(device_id)
  302. callback_task(500, '任务执行失败,无法正常关闭评论框', task_id, device_id, 0, None)
  303. return return_dict
  304. action10_id = int(round(time.time() * 1000))
  305. """
  306. 发送第10条指令
  307. 关闭评论框
  308. """
  309. action10_dict = single_click_by_control(action10_id, target_app="douyin", target_version="28.8.0",
  310. package_name="com.ss.android.ugc.aweme.lite",
  311. control_id="com.ss.android.ugc.aweme.lite:id/back_btn",
  312. control_ids="com.ss.android.ugc.aweme.lite:id/back_btn,"
  313. "com.ss.android.ugc.aweme.lite:id/back",
  314. timeout=5)
  315. redis_client.set(device_id + "operate", action10_id)
  316. redis_client.set(f"{device_id}_step10", "1")
  317. redis_client.delete(f"{device_id}_step9")
  318. loggerKit.info("任务:{0}, action10_id,关闭评论", task_id)
  319. return action10_dict
  320. step10 = redis_client.get(f"{device_id}_step10")
  321. if step10 is not None and int(step10) == 1 and last_action_id is not None and int(perform_action_id) == int(
  322. last_action_id):
  323. action11_id = int(round(time.time() * 1000))
  324. """
  325. 发送第11条指令
  326. 滑动10-15个视频
  327. """
  328. swipe_count = random.randint(5, 10)
  329. action11_dict = continual_swipe_screen(action11_id,
  330. package_name="com.ss.android.ugc.aweme.lite",
  331. continuous_time_interval='3,10',
  332. continuous_count=swipe_count)
  333. redis_client.set(device_id + "operate", action11_id)
  334. redis_client.set(f"{device_id}_step11", "1")
  335. redis_client.delete(f"{device_id}_step10")
  336. loggerKit.info("任务:{0}, action11_id,继续滑动10-15", task_id)
  337. return action11_dict
  338. # 停止
  339. step11 = redis_client.get(f"{device_id}_step11")
  340. if step11 is not None and int(step11) == 1 and last_action_id is not None and int(perform_action_id) == int(
  341. last_action_id):
  342. loggerKit.info("设备:{0}, action11_id_mem:{1}", device_id, int(last_action_id))
  343. action12_id = int(round(time.time() * 1000))
  344. """
  345. 发送第12条指令
  346. 关闭
  347. """
  348. action12_dict = stop_app(action12_id, target_app="douyin", target_version="28.8.0",
  349. package_name="com.ss.android.ugc.aweme.lite", timeout=5)
  350. # redis_client.set(device_id + "operate", action12_id)
  351. # redis_client.set(f"{device_id}_step12", "1")
  352. # redis_client.delete(f"{device_id}_step11")
  353. loggerKit.info("任务:{0}, action12_id,停止app", task_id)
  354. del_key_vague(device_id)
  355. # 回调任务中心修改任务状态
  356. callback_task(None, None, task_id, device_id, 1, None)
  357. return action12_dict
  358. else:
  359. action0_id = int(round(time.time() * 1000))
  360. """
  361. 启动指令
  362. 启动app
  363. """
  364. action0_dict = start_app(action0_id, target_app="douyin", target_version="29.5.0",
  365. package_name="com.ss.android.ugc.aweme.lite")
  366. redis_client.set(device_id + "operate", action0_id)
  367. redis_client.set(f"{device_id}_step0", "1")
  368. redis_client.delete(f"{device_id}_step9")
  369. loggerKit.info("设备:{0}, action0_id:{1}", device_id, action0_id)
  370. return action0_dict
  371. # 批量模糊删除缓存
  372. # def del_key_vague(device_id):
  373. # # 批量模糊删除keys
  374. # keys = redis_client.match_pattern_prefix(device_id)
  375. # if len(keys) > 0:
  376. # # 需要判断是否有匹配的值, 没有的话会报错
  377. # for key in keys:
  378. # redis_client.delete(key)
  379. # loggerKit.info(f"clear {device_id} keys success...")
  380. # else:
  381. # loggerKit.info(f"{device_id} keys none ...")