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