search_key_mac.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. # -*- coding: utf-8 -*-
  2. # @Author: wangkun
  3. # @Time: 2023/2/20
  4. """
  5. 1. 安装 atomac:
  6. 1.1.翻墙
  7. 1.2.pip3 install git+https://github.com/pyatom/pyatom/
  8. 2. 启动 Charles.exe:
  9. 2.1 选中 Proxy - Windows Proxy
  10. 2.2 选中 Tools - Auto Save - Enable Auto Save
  11. 3. 启动 Python 脚本:
  12. 3.1 cd ./piaoquan_crawler/
  13. 3.2 python ./weixinzhishu/weixinzhishu_main/search_key_mac.py
  14. 4. 每 10 秒获取最新search_key,写入飞书: https://w42nne6hzg.feishu.cn/sheets/shtcnqhMRUGunIfGnGXMOBYiy4K?sheet=sVL74k
  15. """
  16. from datetime import datetime
  17. import json
  18. import os
  19. import sys
  20. import time
  21. import atomac
  22. sys.path.append(os.getcwd())
  23. from common.common import Common
  24. from common.feishu import Feishu
  25. class SearchKey:
  26. # 启动微信 / 微信指数小程序 ; 关闭微信 / 微信指数小程序
  27. @classmethod
  28. def start_wechat(cls, log_type, crawler):
  29. try:
  30. # 启动应用并获取应用信息
  31. bundle_id = "com.tencent.xinWeChat"
  32. Common.logger(log_type, crawler).info("启动微信")
  33. atomac.launchAppByBundleId(bundle_id)
  34. automator = atomac.getAppRefByBundleId(bundle_id)
  35. time.sleep(1)
  36. # 获取当前应用window
  37. window = automator.windows()[0]
  38. Common.logger(log_type, crawler).info(f"当前应用window:{window.AXTitle}")
  39. # # 登录
  40. # login_btn = window.findFirstR(AXRole="AXButton", AXDescription="进入微信")
  41. # # print(login_btn.getAttributes())
  42. # # print(f"AXEnabled:{login_btn.AXEnabled}")
  43. # # print(f"AXDescription:{login_btn.AXDescription}")
  44. # # print(f"AXParent:{login_btn.AXParent}")
  45. # # print(f"AXSize:{login_btn.AXSize}")
  46. # # print(f"AXFocused:{login_btn.AXFocused}")
  47. # # print(f"AXRole:{login_btn.AXRole}")
  48. # # print(f"AXTopLevelUIElement:{login_btn.AXTopLevelUIElement}")
  49. # # print(f"AXHelp:{login_btn.AXHelp}")
  50. # # print(f"AXPosition:{login_btn.AXPosition}")
  51. # # print(f"AXWindow:{login_btn.AXWindow}")
  52. # # print(f"AXRoleDescription:{login_btn.AXRoleDescription}")
  53. # # print(f"AXIdentifier:{login_btn.AXIdentifier}")
  54. # if login_btn:
  55. # Common.logger(log_type, crawler).info("发现登录按钮,点击登录")
  56. # login_btn.Press()
  57. # time.sleep(1)
  58. # 查找聊天按钮
  59. Common.logger(log_type, crawler).info("查找聊天按钮")
  60. chat_btn = window.findFirstR(AXHelp="微信", AXRole="AXRadioButton")
  61. # 点击聊天按钮,展开聊天列表
  62. Common.logger(log_type, crawler).info("点击聊天按钮")
  63. chat_btn.Press()
  64. time.sleep(1)
  65. # 查找文件传输助手
  66. Common.logger(log_type, crawler).info("查找文件传输助手")
  67. chat_help = window.findFirstR(AXIdentifier="MMChatsTableCellView_0" ,AXRole="AXCell")
  68. Common.logger(log_type, crawler).info(f"文件传输助手:{chat_help}")
  69. chat_help_position = chat_help.AXPosition
  70. chat_help_size = chat_help.AXSize
  71. chat_help_coor = (abs(chat_help_position[0])+chat_help_size[0]/2, abs(chat_help_position[1])+chat_help_size[1]/2)
  72. Common.logger(log_type, crawler).info(f"文件传输助手坐标:{chat_help_coor}")
  73. Common.logger(log_type, crawler).info("点击文件传输助手")
  74. for i in range(2):
  75. chat_help.clickMouseButtonLeft(chat_help_coor)
  76. time.sleep(1)
  77. # 查找微信指数小程序消息
  78. Common.logger(log_type, crawler).info("查找微信指数小程序消息")
  79. weixinzhishu = window.findFirstR(AXValue="微信指数", AXRole="AXStaticText")
  80. Common.logger(log_type, crawler).info(f"微信指数小程序:{weixinzhishu}")
  81. weixinzhishu_box = weixinzhishu.AXPosition
  82. weixinzhishu_position = weixinzhishu.AXSize
  83. weixinzhishu_coord = (abs(weixinzhishu_box[0])+weixinzhishu_position[0]/2, abs(weixinzhishu_box[1])+weixinzhishu_position[1])
  84. Common.logger(log_type, crawler).info(f"微信指数小程序坐标:{weixinzhishu_coord}")
  85. Common.logger(log_type, crawler).info("点击微信指数小程序消息")
  86. for i in range(2):
  87. weixinzhishu.clickMouseButtonLeft(weixinzhishu_coord)
  88. time.sleep(3)
  89. close_wechat = window.findFirstR(AXSubrole="AXCloseButton", AXRole="AXButton")
  90. close_wechat.Press()
  91. time.sleep(1)
  92. Common.logger(log_type, crawler).info("关闭微信成功")
  93. Common.logger(log_type, crawler).info("关闭微信指数小程序")
  94. time.sleep(15)
  95. cmd = "ps aux | grep Program.app | grep -v grep | awk '{print $2}' | xargs kill -9"
  96. os.system(cmd)
  97. Common.logger(log_type, crawler).info("微信指数小程序关闭成功")
  98. time.sleep(1)
  99. except Exception as e:
  100. Common.logger(log_type, crawler).info(f"start_wechat:{e}\n")
  101. # 获取微信指数小程序 search_key
  102. @classmethod
  103. def get_wechat_key(cls, log_type, crawler):
  104. try:
  105. while True:
  106. chlsfile_path = f"./{crawler}/{crawler}_chlsfiles/"
  107. if len(os.listdir(chlsfile_path)) == 0:
  108. Common.logger(log_type, crawler).info("chlsfile文件夹空,等待 3 秒")
  109. time.sleep(3)
  110. cls.start_wechat(log_type, crawler)
  111. continue
  112. Common.logger(log_type, crawler).info(f"chlsfile_list:{sorted(os.listdir(chlsfile_path))}")
  113. # 获取最新的 chlsfile
  114. chlsfile = sorted(os.listdir(chlsfile_path))[-1]
  115. # 分离文件名与扩展名
  116. new_file = os.path.splitext(chlsfile)
  117. # 重命名文件后缀
  118. os.rename(os.path.join(chlsfile_path, chlsfile),
  119. os.path.join(chlsfile_path, new_file[0] + ".txt"))
  120. with open(f"{chlsfile_path}{new_file[0]}.txt", encoding='utf-8-sig', errors='ignore') as f:
  121. contents = json.load(f, strict=False)
  122. if "search.weixin.qq.com" not in [text['host'] for text in contents]:
  123. return "未找到wechat_key"
  124. else:
  125. for content in contents:
  126. if content["host"] == "search.weixin.qq.com" and content["path"] == "/cgi-bin/wxaweb/wxawebreport":
  127. # print(f"content:{content}")
  128. text = content['request']['body']['text']
  129. search_key = json.loads(text)['search_key']
  130. openid = json.loads(text)['openid']
  131. wechat_key_dict = {
  132. "search_key": search_key,
  133. "openid": openid,
  134. }
  135. return wechat_key_dict
  136. elif content["host"] == "search.weixin.qq.com" and content["path"] == "/cgi-bin/wxaweb/wxindexgetusergroup":
  137. text = content['request']['body']['text']
  138. search_key = json.loads(text)['search_key']
  139. openid = json.loads(text)['openid']
  140. wechat_key_dict = {
  141. "search_key": search_key,
  142. "openid": openid,
  143. }
  144. return wechat_key_dict
  145. else:
  146. return "未找到wechat_key"
  147. except Exception as e:
  148. Common.logger(log_type, crawler).error(f"get_wechat_key:{e}\n")
  149. # 删除 chlsfile 文件
  150. @classmethod
  151. def remove_chlsfile(cls, log_type, crawler):
  152. try:
  153. all_file_path = f"./{crawler}/{crawler}_chlsfiles/"
  154. if not os.path.exists(all_file_path):
  155. os.mkdir(all_file_path)
  156. all_file = os.listdir(all_file_path)
  157. for file in all_file:
  158. os.remove(f"./{crawler}/{crawler}_chlsfiles/{file}")
  159. except Exception as e:
  160. Common.logger(log_type, crawler).error(f"remove_file异常:{e}\n")
  161. # 删除微信指数小程序 search_key
  162. @classmethod
  163. def del_wechat_key(cls, log_type, crawler):
  164. try:
  165. while True:
  166. sheet = Feishu.get_values_batch(log_type, crawler, 'sVL74k')
  167. if sheet is None:
  168. Common.logger(log_type, crawler).info(f"wechat_key_sheet:{sheet}, 1秒后重新获取")
  169. time.sleep(1)
  170. continue
  171. if len(sheet) <= 51:
  172. return
  173. else:
  174. Feishu.dimension_range(log_type, crawler, 'sVL74k', 'ROWS', 52, 52)
  175. except Exception as e:
  176. Common.logger(log_type, crawler).error(f"del_wechat_key异常:{e}\n")
  177. # 微信指数小程序 search_key 写入飞书
  178. @classmethod
  179. def write_wechat_key(cls, log_type, crawler):
  180. try:
  181. Common.logger(log_type, crawler).info(f"清空 chlsfiles 文件夹")
  182. cls.remove_chlsfile(log_type, crawler)
  183. Common.logger(log_type, crawler).info('获取 wechat_key')
  184. while True:
  185. cls.start_wechat(log_type, crawler)
  186. wechat_key_dict = cls.get_wechat_key(log_type, crawler)
  187. if wechat_key_dict is None or wechat_key_dict == "未找到wechat_key":
  188. Common.logger(log_type, crawler).info("未找到wechat_key,重新获取")
  189. time.sleep(1)
  190. continue
  191. for k, v in wechat_key_dict.items():
  192. Common.logger(log_type, crawler).info(f"{k}:{v}")
  193. Feishu.insert_columns(log_type, crawler, 'sVL74k', 'ROWS', 1, 2)
  194. time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(time.time())))
  195. values = [[time_str, wechat_key_dict['search_key'], wechat_key_dict['openid']]]
  196. time.sleep(1)
  197. Feishu.update_values(log_type, crawler, 'sVL74k', 'A2:Z2', values)
  198. cls.del_wechat_key(log_type, crawler)
  199. Common.logger(log_type, crawler).info("wechat_key写入飞书成功")
  200. Common.del_logs(log_type, crawler)
  201. return
  202. except Exception as e:
  203. Common.logger(log_type, crawler).error(f"write_wechat_key:{e}\n")
  204. @classmethod
  205. def main(cls, log_type, crawler):
  206. while True:
  207. if 11 <= datetime.now().hour < 14:
  208. cls.write_wechat_key(log_type, crawler)
  209. Common.logger(log_type, crawler).info('休眠10秒\n')
  210. time.sleep(10)
  211. else:
  212. Common.logger(log_type, crawler).info("休眠中,获取 search_key 的时间段为: 11:00:00 - 13:59:59")
  213. time.sleep(60)
  214. if __name__ == "__main__":
  215. SearchKey.main("search", "weixinzhishu")
  216. pass