From 91b7ec2b67d74e4d2e41c857232414feb3cb7bfd Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期三, 02 四月 2025 18:32:10 +0800 Subject: [PATCH] 功能完善 --- comment_manager.py | 19 ++++- icon.ico | 0 video_manager.py | 10 +-- main.spec | 2 constant.py | 6 ++ res/setting.conf | 18 ++++-- res/comment.txt | 8 ++ comment.py | 113 +++++++++++++++++++++++++++---------- 8 files changed, 127 insertions(+), 49 deletions(-) diff --git a/comment.py b/comment.py index cdbd18c..78365b8 100644 --- a/comment.py +++ b/comment.py @@ -1,3 +1,6 @@ +import json +import os +import random import threading import time @@ -9,6 +12,7 @@ from selenium.webdriver.support import expected_conditions as EC import comment_manager +import constant import setting from video_manager import VideoManger @@ -23,9 +27,9 @@ # driver = webdriver.Chrome(options=options) # 鍙﹀涓�绉嶆柟寮� # 璋锋瓕娴忚鍣ㄤ綅缃� - chrome_location = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' + chrome_location = setting.get_chrome_path() # 璋锋瓕娴忚鍣ㄩ┍鍔ㄥ湴鍧� - chromedriver_path = r'chromedriver.exe' + chromedriver_path = setting.get_chromedriver_path() self.options.binary_location = chrome_location # 鎸囧畾chrome鐨勮矾寰� self.service = Service(chromedriver_path) # 鑾峰彇姝e垯琛ㄨ揪寮� @@ -35,23 +39,48 @@ self.comment_templates = [(x.split("#")[0], x.split("#")[1]) for x in comment_template_str.split("\n") if x.find("#") >= 0] self.driver = None + self.break_excute = False # 涓柇鎵ц + + def break_excute(self): + """ + 涓柇鎵ц + :return: + """ + print("=====涓柇鎵ц=====") + self.break_excute = True def __init(self): + self.break_excute = False if not self.driver: self.driver = webdriver.Chrome(service=self.service, options=self.options) + self.driver.get( + "https://channels.weixin.qq.com/platform/comment?isImageMode=0") + else: + self.driver.refresh() def start_process_comment(self): """ 寮�濮嬪鐞嗚瘎璁� :return: """ + while True: + try: + self.__start_excute_task() + except: + pass + finally: + time.sleep(constant.REFRESH_TIME_SPACE) + + def __start_excute_task(self): + """ + 寮�濮嬫墽琛屼换鍔� + :return: + """ self.__init() - self.driver.get( - "https://channels.weixin.qq.com/platform/comment?isImageMode=0") # 绛夊埌宸︿晶鑿滃崟鍑虹幇鍚庢墠鑳芥墽琛屽悗缁搷浣� - wait = WebDriverWait(self.driver, 100) # 鏈�澶氱瓑寰�10绉� + wait = WebDriverWait(self.driver, 1000000) # 鏈�澶氱瓑寰�10绉� element = wait.until(EC.visibility_of_element_located((By.ID, "side-bar"))) - threading.Thread(target=lambda: self.process_videos(self.driver), daemon=True).start() + self.process_videos(self.driver) def __process_like(self, video_name, video_date, comment_element): """ @@ -83,7 +112,10 @@ """ user_name = comment_element.find_element(By.CLASS_NAME, "comment-user-name").get_attribute("innerHTML") comment_time = comment_element.find_element(By.CLASS_NAME, "comment-time").get_attribute("innerHTML") - comment_content = comment_element.find_element(By.CLASS_NAME, "comment-content").get_attribute("innerHTML") + try: + comment_content = comment_element.find_element(By.CLASS_NAME, "comment-content").get_attribute("innerHTML") + except: + comment_content = '' return user_name, comment_content, comment_time def __parse_video_info(self, video_element): @@ -96,14 +128,16 @@ comment_count = video_element.find_element(By.CLASS_NAME, "feed-comment-total").find_element(By.XPATH, "./span[2]").get_attribute( "innerHTML") - video_name = video_element.find_element(By.CLASS_NAME, "comment-content").get_attribute("innerHTML") - return video_name, video_time, comment_count + video_name = video_element.find_element(By.CLASS_NAME, "feed-title").get_attribute("innerHTML") + video_title = video_name + if video_title.find("#") >= 0: + video_title = video_title[:video_title.find("#")] + return video_name, video_time, comment_count, video_title - def __process_reply(self, video_name, video_date, comment_element): + def __process_reply(self, video_info, comment_element): """ 澶勭悊鍗曟潯璇勮鍥炲 - :param video_name: - :param video_date: + :param video_name:(video_name, video_date, comment_count, video_title) :param comment_element: :return: 鏄惁闇�瑕佺偣璧� """ @@ -112,7 +146,7 @@ if not setting.is_reply_comment(): return None # 鍐呭鏄惁绗﹀悎鏍囧噯 - return comment_manager.get_replay_content(video_name, video_date, nick_name, content) + return comment_manager.get_replay_content(video_info, nick_name, content) comment_user_name, comment_content, comment_time = self.__parse_comment_info(comment_element) @@ -124,7 +158,7 @@ except: print("杩樻病鍥炲銆傘�傘�傘��") - replay_content = get_reply_comment(comment_user_name, comment_element) + replay_content = get_reply_comment(comment_user_name, comment_content) if not replay_content: # 涓嶉渶瑕佽瘎璁� print("涓嶉渶瑕佸洖澶嶃�傘�傘�傘��") @@ -136,7 +170,7 @@ "action-item") # 鐐瑰嚮璇勮 comment_actions[1].click() - wait = WebDriverWait(self.driver, 5) # 鏈�澶氱瓑寰�10绉� + wait = WebDriverWait(self.driver, 10) # 鏈�澶氱瓑寰�10绉� wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "comment-create-content"))) time.sleep(1) self.driver.find_element(By.CLASS_NAME, @@ -146,6 +180,7 @@ self.driver.find_element(By.CLASS_NAME, "comment-create-content").find_element(By.XPATH, "div[3]/div[2]").click() time.sleep(2) + time.sleep(random.randint(constant.COMMENT_REPLY_SPACE_TIME_MIN, constant.COMMENT_REPLY_SPACE_TIME_MAX)) return False def __process_comments(self, driver, start_index=0, video_info=None): @@ -153,26 +188,30 @@ :param driver: :param start_index: - :param video_info:(瑙嗛鍐呭, 瑙嗛鏃ユ湡, 璇勮娆℃暟) + :param video_info:(瑙嗛鍐呭, 瑙嗛鏃ユ湡, 璇勮娆℃暟, 瑙嗛鏍囬) :return: """ scroll_list = driver.find_element(By.CLASS_NAME, "feed-comment__wrp") - - loadmore = scroll_list.find_element(By.CLASS_NAME, "loadmore__dot") - # 鑾峰彇鐖舵帶浠� - loadmore = loadmore.find_element(By.XPATH, "./..") - has_more = loadmore.value_of_css_property("display") == "none" + try: + loadmore = scroll_list.find_element(By.CLASS_NAME, "loadmore__dot") + # 鑾峰彇鐖舵帶浠� + loadmore = loadmore.find_element(By.XPATH, "./..") + has_more = loadmore.value_of_css_property("display") == "none" + except: + has_more = False comments = scroll_list.find_elements(By.XPATH, "div[2]/div/div/div[contains(@class,'comment-item')]") print("璇勮鏉℃暟", len(comments)) for index in range(start_index, len(comments)): + if self.break_excute: + return comment = comments[index] # 璇勮鍐呭 user_name, comment_content, comment_time = self.__parse_comment_info(comment) if not comment_content: - continue + comment_content = '' print("=======璇勮鍐呭锛�", comment_content) - need_like = self.__process_reply(video_info[0], video_info[1], comment) + need_like = self.__process_reply(video_info, comment) if need_like: print("闇�瑕佺偣璧�") self.__process_like(video_info[0], video_info[1], comment) @@ -184,9 +223,9 @@ "var __comment_scroll = document.getElementsByClassName('feed-comment__wrp')[0]; __comment_scroll.scrollTop = __comment_scroll.scrollHeight;") print("寰�涓嬫粴鍔�") time.sleep(3) - self.__process_comments(driver, start_index=len(comments)) + self.__process_comments(driver, start_index=len(comments), video_info=video_info) else: - print("娌℃湁鏇村璇勮浜�") + print("娌℃湁鏇村璇勮浜�, 璇勮鏁伴噺锛�", len(comments)) def process_videos(self, driver: webdriver.Chrome, start_index=0): wait = WebDriverWait(driver, 100) # 鏈�澶氱瓑寰�10绉� @@ -196,18 +235,20 @@ videos_root = driver.find_element(By.CLASS_NAME, "feeds-container") videos = videos_root.find_elements(By.CLASS_NAME, "comment-feed-wrap") for i in range(start_index, len(videos)): + if self.break_excute: + return # 閫夋嫨瑙嗛 video = videos[i] # 瑙f瀽瑙嗛鍐呭 - video_name, video_time, comment_count = self.__parse_video_info(video) + video_info = self.__parse_video_info(video) # 鍒ゆ柇鏄惁瑕佺偣鍑昏繘鍘� - if not VideoManger().is_need_click(video_name, video_time, comment_count): + if not VideoManger().is_need_click(video_info): continue video.click() driver.implicitly_wait(2) - self.__process_comments(driver, video_info=(video_name, video_time, comment_count)) - # 5s澶勭悊涓�涓棰� - time.sleep(5) + self.__process_comments(driver, video_info=video_info) + # 澶勭悊涓�涓棰� + time.sleep(constant.VIDEO_CLICK_SPACE_TIME) loadmore = scroll_list.find_element(By.CLASS_NAME, "loadmore__dot") # 鑾峰彇鐖舵帶浠� @@ -230,6 +271,18 @@ except: pass + def __save_cookie(self): + cookies = self.driver.get_cookies() + with open("datas/cookies.json", "w") as f: + json.dump(cookies, f) + + def __fill_cookie(self): + if os.path.exists("datas/cookies.json"): + with open("datas/cookies.json", "r") as f: + cookies = json.load(f) + for cookie in cookies: + self.driver.add_cookie(cookie) + if __name__ == "__main__": # CommentManager().start_process_comment() diff --git a/comment_manager.py b/comment_manager.py index 4c72cd4..66040da 100644 --- a/comment_manager.py +++ b/comment_manager.py @@ -3,6 +3,8 @@ """ # 淇濆瓨鍥炲瑙嗛璇勮鐨勭敤鎴锋樀绉� # {"瑙嗛鍚嶇О+鍙戝竷鏃ユ湡":{"璇勮鐢ㄦ埛鐨勬樀绉�":{"璇勮鍐呭闆嗗悎"}}} +import re + import comment_util __reply_video_comment_user_name_dict = {} @@ -24,15 +26,16 @@ __reply_video_comment_user_name_dict[k][comment_nick_name].add(comment_content) -def get_replay_content(video_name, video_date, comment_nick_name, comment_content): +def get_replay_content(video_info, comment_nick_name, comment_content): """ 鑾峰彇鍥炲鍐呭 - :param video_name:瑙嗛鍚嶇О - :param video_date:瑙嗛鏃ユ湡 + :param video_info:(瑙嗛鍚嶇О, 鏃ユ湡, 璇勮娆℃暟, 瑙嗛鏍囬) :param comment_nick_name:璇勮鏄电О :param comment_content:璇勮鍐呭 :return: """ + video_name, video_date, video_title = video_info[0], video_info[1], video_info[3] + k = f"{video_name}{video_date}" if k not in __reply_video_comment_user_name_dict: __reply_video_comment_user_name_dict[k] = {} @@ -51,7 +54,13 @@ comment_content = comment_util.replace_img_with_alt(comment_content) for r in comment_templates: - if r.match(r[0], comment_content): + is_match = False + if r[0].find("銆愯棰戞爣棰樸��") >= 0: + if comment_content.find(video_title)>=0: + is_match = True + elif re.match(r[0], comment_content): + is_match = True + if is_match: # 鑳藉鍖归厤鍒版鍒欒〃杈惧紡 result = comment_util.load_content(r[1], comment_nick_name, comment_content) if result: @@ -75,7 +84,7 @@ # 鏇挎崲璇勮鍐呭涓殑img comment_content = comment_util.replace_img_with_alt(comment_content) for r in like_conditions: - if r.match(r, comment_content): + if re.match(r, comment_content): # 鑳藉鍖归厤鍒版鍒欒〃杈惧紡 return True return False diff --git a/constant.py b/constant.py new file mode 100644 index 0000000..b97a196 --- /dev/null +++ b/constant.py @@ -0,0 +1,6 @@ +REFRESH_TIME_SPACE = 30 * 60 # 鍒锋柊鏃堕棿 30鍒嗛挓 +VIDEO_CLICK_SPACE_TIME = 20 # 瑙嗛鍒囨崲鏃堕棿闂撮殧 +COMMENT_REPLY_SPACE_TIME_MIN = 5 # 璇勮鏃堕棿闂撮殧鏈�灏忓�� +COMMENT_REPLY_SPACE_TIME_MAX = 20 # 璇勮鏃堕棿闂撮殧鏈�澶у�� + + diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..6b27eba --- /dev/null +++ b/icon.ico Binary files differ diff --git a/main.spec b/main.spec index a664321..9c8a6db 100644 --- a/main.spec +++ b/main.spec @@ -59,5 +59,5 @@ strip=False, upx=True, upx_exclude=[], - name='kp', + name='瑙嗛鍙峰姪鎵�', ) diff --git a/res/comment.txt b/res/comment.txt index 9f5db64..4fa3320 100644 --- a/res/comment.txt +++ b/res/comment.txt @@ -1,4 +1,10 @@ .*涓嶅.*#{鏄殑锛屼綘鐨勮鐐瑰緢璧瀨濂藉惂[鐖卞績]|璋㈣阿[鎶辨嫵]|鏄殑[寮篯|纭疄鍙兘鏈変簺涓嶅[瑁傚紑]} .*瀵�.*|.*鏀寔.*|.*娌℃瘺鐥�.*|.*涓�鏍�.*|.*娌¢敊.*|.*鏈夐亾鐞�.*#{鎰熻阿浣犵殑璁ゅ悓|鎰熻阿浣犵殑璇勪环|璋㈣阿浣犵殑璁ゅ悓|鎰熸仼浣犵殑璁ゅ悓|璋㈣阿浣犵殑璇勮|鎰熸仼浣犵殑璁ゅ彲|鏄殑锛屼綘璇寸殑娌¢敊|浣犵殑璁ゅ悓鎴戝緢鎰熸縺}{銆�1-3銆憓 .*澶皯浜�.*#{鏄殑锛岀‘瀹炰笉澶殅{銆�1-3銆憓 - +^(\[\w+\])+$#銆愭渶鍚庝竴涓〃鎯呫�戙��1-3銆�#鍙湁琛ㄦ儏 +.*銆愯棰戞爣棰樸��.*#{鎰熻阿浣犵殑璇勮|鎰熻阿浣犵殑鏀寔}銆�1-3銆� #1:1澶嶅埗鏂囨 +*鍠滄*#{濂藉惂|鎰熻阿鍠滄|鍠滄灏卞ソ|鑳借浣犲枩娆㈢湡寮�蹇儅 +^[^\[\]]*$|^(?!.*\[\w+\]).*$#銆愬唴瀹广�戙��1-3銆�#涓嶅寘鍚玡moji琛ㄦ儏锛屽彧鏈変竴娈垫枃瀛� +.*\[.*?\].*#銆愭渶鍚庝竴涓〃鎯呫�戙��1-3銆�#鍖呭惈emoji +.*鏃╁畨.*#{鏃╀笂濂絴鏃╁畨|鏃╀笂濂藉晩|鏃╁畨鍜瘄鏃╁晩|绁濅綘鏃╀笂濂絴绁濅綘鏃╀笂寮�蹇億绁濅綘鏃╁畨}銆�1-3銆�# +.*鐢熸棩.*#銆愭樀绉般�憑[铔嬬硶]|[铔嬬硶][铔嬬硶]|[铔嬬硶][铔嬬硶][铔嬬硶]}# \ No newline at end of file diff --git a/res/setting.conf b/res/setting.conf index 22cd13a..2d99ae1 100644 --- a/res/setting.conf +++ b/res/setting.conf @@ -1,12 +1,18 @@ [config] -comment_templates = [*]$#[*] - 不对# - 对# - ^你#123123 +comment_templates = .*生日.*#【昵称】{[蛋糕]|[蛋糕][蛋糕]|[蛋糕][蛋糕][蛋糕]}# + .*不对.*#{是的,你的观点很赞|好吧[爱心]|谢谢[抱拳]|是的[强]|确实可能有些不对[裂开]} + .*对.*|.*支持.*|.*没毛病.*|.*一样.*|.*没错.*|.*有道理.*#{感谢你的认同|感谢你的评价|谢谢你的认同|感恩你的认同|谢谢你的评论|感恩你的认可|是的,你说的没错|你的认同我很感激}{【1-3】} + .*太少了.*#{是的,确实不多}{【1-3】} + ^(\[\w+\])+$#【最后一个表情】【1-3】#只有表情 + .*【视频标题】.*#{感谢你的评论|感谢你的支持}【1-3】 #1:1复制文案 + *喜欢*#{好吧|感谢喜欢|喜欢就好|能让你喜欢真开心} + ^[^\[\]]*$|^(?!.*\[\w+\]).*$#【内容】【1-3】#不包含emoji表情,只有一段文字 + .*\[.*?\].*#【最后一个表情】【1-3】#包含emoji + .*早安.*#{早上好|早安|早上好啊|早安咯|早啊|祝你早上好|祝你早上开心|祝你早安}【1-3】# reply_comment = 1 click_like = 1 chromedriver_path = D:\workspace\python\wechat_helper\chromedriver.exe -chrome_path = D:\workspace\python\wechat_helper\chromedriver.exe +chrome_path = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe common_emojis = [爱心] [合十] [拥抱] [抱拳] [强] [玫瑰] [胜利] [666] [呲牙] [愉快] -like_conditions = [\u4e00-\u9fa5]{2,}#最少2个字中文 +like_conditions = ^$#空白评论内容 diff --git a/video_manager.py b/video_manager.py index eb6d74e..6fb6832 100644 --- a/video_manager.py +++ b/video_manager.py @@ -18,18 +18,17 @@ if lines: self.__video_data_cache_dict = eval(lines[0]) - def is_need_click(self, video_name, video_time, comment_count): + def is_need_click(self, video_info): """ 鏄惁闇�瑕佺偣鍑� - :param video_name: 瑙嗛鍚嶇О - :param video_time: 瑙嗛鏃堕棿 - :param comment_count: 璇勮鏁伴噺 + :param video_info: :return: """ + video_name, video_time, comment_count = video_info[0], video_info[1], video_info[2] k = f"{video_name}{video_time}" if k not in self.__video_data_cache_dict: return True - if comment_count - self.__video_data_cache_dict[k][0] > 0: + if int(comment_count) - int(self.__video_data_cache_dict[k][0]) > 0: return True return False @@ -44,4 +43,3 @@ # 淇濆瓨鍒版枃浠� with open(self.__video_cache_path, encoding="utf-8", mode='w') as f: f.write(f"{self.__video_data_cache_dict}") - -- Gitblit v1.8.0