search_key_mac.py 11 KB

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