基于 Selenium 和 API 的微信网页版自动回复程序:实现、功能与异常处理全解析

 阅码专用背景音乐:1、网易云音乐  2、网易云音乐

适用场景:

一、客服场景

  1. 电商客服
    • 在电商行业,商家可能会收到大量顾客关于商品信息、价格、物流等方面的咨询。微信自动回复程序可以快速响应顾客的基本问题。例如,当顾客询问某件商品是否有货时,程序可以立即回复库存情况。如果库存充足,回复 “该商品有货,您可以随时下单”;若缺货,回复 “很抱歉,此商品目前缺货,您可以留下联系方式,到货后我们会第一时间通知您”。
    • 对于商品的价格问题,程序可以根据预先设置的价格规则进行回复。比如顾客询问某商品的促销价格,程序可以准确地告知其活动价格和活动时间,提高顾客的购物体验,同时减轻客服人员的工作负担。
  2. 企业客服
    • 企业在处理客户咨询、售后问题时,也可以利用微信自动回复程序。当客户咨询产品的使用方法时,程序可以提供常见问题解答文档链接或简单的操作步骤。例如,一家软件公司收到用户关于软件安装问题的咨询,自动回复可以是 “您可以参考我们官网的安装指南链接 [具体链接],如果还有问题,请详细描述您遇到的情况”。

二、营销场景

  1. 活动推广
    • 当企业或品牌开展营销活动时,自动回复程序可以用于活动宣传。例如,商家举办抽奖活动,当用户在微信咨询活动详情时,程序可以自动发送活动规则、参与方式和奖品信息。像 “我们正在进行抽奖活动,您只需关注我们的公众号并转发活动推文,即可参与抽奖,奖品包括 [具体奖品清单]”。
    • 对于新推出的产品或服务,自动回复可以发送产品介绍、优惠信息等营销内容。如一家培训机构推出新的课程,当有用户询问时,自动回复可以是 “我们新推出了 [课程名称] 课程,现在报名可享受 [X] 折优惠,课程内容包括 [详细内容介绍]”。
  2. 引流获客
    • 自动回复程序可以设置为引导用户留下联系方式。例如,通过回复 “如果您想了解更多关于我们产品的深度信息,您可以留下您的电话号码或者邮箱,我们会安排专人与您联系”,帮助企业收集潜在客户的信息,方便后续的销售跟进。

三、个人事务繁忙场景

  1. 工作忙碌时
    • 对于一些工作繁忙的个人,可能无法及时回复微信消息。比如程序员在集中精力开发代码时,或者销售人员在与客户面谈时。自动回复程序可以设置简单的回复内容,如 “我现在正在忙,稍后会回复您的消息”,避免让对方等待过久而产生误解。
  2. 休假期间
    • 在休假的时候,也可以使用自动回复告知联系人自己的状态。例如 “我目前在休假中,如非紧急情况,请在 [具体日期] 之后联系我,紧急情况可以拨打 [电话号码]”。

 以上应用场景均不是该代码的功能:以下才是

你还在为吵架骂不过别人而烦恼吗?本代码致力于别人说一句回万句,主打一个以量取胜!你以为别人不回复就没事了吗?不!代码会持续输出!十几句十几句的继续攻破对方!

import logging
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
import json
import sys
import msvcrt
import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import (
    NoSuchElementException,
    TimeoutException,
    WebDriverException
)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('wechat_auto_reply.log'),
        logging.StreamHandler()
    ]
)

@dataclass
class Config:
    """配置类,用于管理所有配置参数"""
    chromedriver_path: str
    extension_path: str
    api_url: str
    api_key: str
    wait_timeout: int = 30
    retry_interval: int = 1

    @classmethod
    def load_from_file(cls, config_path: str = 'config.json') -> 'Config':
        """从配置文件加载配置"""
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config_data = json.load(f)
            return cls(**config_data)
        except FileNotFoundError:
            logging.error(f"配置文件 {config_path} 不存在")
            raise
        except json.JSONDecodeError:
            logging.error(f"配置文件 {config_path} 格式错误")
            raise

class WeChatAutoReply:
    def __init__(self, config: Config):
        self.config = config
        self.driver = None
        self.wait = None
        self.setup_driver()

    def setup_driver(self):
        """设置并初始化WebDriver"""
        try:
            service = Service(executable_path=self.config.chromedriver_path)
            options = webdriver.ChromeOptions()
            if Path(self.config.extension_path).exists():
                options.add_argument(f'--load-extension={self.config.extension_path}')
            
            self.driver = webdriver.Chrome(service=service, options=options)
            self.wait = WebDriverWait(self.driver, self.config.wait_timeout)
            self.driver.get('https://wx.qq.com/?target=t')
            logging.info("WebDriver初始化成功")
        except WebDriverException as e:
            logging.error(f"WebDriver初始化失败: {e}")
            raise

    def get_api_response(self, message: str) -> Optional[str]:
        """获取API响应"""
        try:
            url = f'{self.config.api_url}?key={self.config.api_key}&appid=0&msg={message}'
            response = requests.get(url, timeout=10)
            response.raise_for_status()
            content = response.json().get('content', '').replace('(br)', '')
            return content
        except requests.RequestException as e:
            logging.error(f"API请求失败: {e}")
            return None

    def send_message(self, content: str):
        """发送消息"""
        try:
            message_input = self.wait.until(
                EC.presence_of_element_located((By.ID, 'editArea'))
            )
            message_input.clear()
            message_input.send_keys(content)
            
            send_button = self.wait.until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.btn.btn_send'))
            )
            send_button.click()
            logging.info(f"成功发送消息: {content[:50]}...")
        except (TimeoutException, NoSuchElementException) as e:
            logging.error(f"发送消息失败: {e}")
            raise

    def handle_new_message(self):
        """处理新消息"""
        try:
            # 检查新消息提示
            new_message = self.wait.until(
                EC.presence_of_element_located(
                    (By.XPATH, "//i[contains(@class, 'icon web_wechat_reddot_middle ng-binding ng-scope')]")
                )
            )
            ActionChains(self.driver).move_to_element(new_message).click().perform()

            # 获取消息内容
            message_element = self.wait.until(
                EC.presence_of_element_located(
                    (By.XPATH, "//pre[contains(@class, 'js_message_plain ng-binding')]")
                )
            )
            message_content = message_element.text

            # 获取并发送回复
            response = self.get_api_response(message_content)
            if response:
                self.send_message(response)

        except TimeoutException:
            self.click_file_helper()
        except Exception as e:
            logging.error(f"处理消息时出错: {e}")
            self.handle_error()

    def click_file_helper(self):
        """点击文件传输助手,保持会话活跃"""
        try:
            file_helper = self.wait.until(
                EC.presence_of_element_located(
                    (By.XPATH, "//span[contains(@class, 'nickname_text ng-binding') and contains(text(),'文件传输助手')]")
                )
            )
            file_helper.click()
        except (TimeoutException, NoSuchElementException) as e:
            logging.warning(f"点击文件传输助手失败: {e}")

    def handle_error(self):
        """错误处理"""
        try:
            self.driver.refresh()
            time.sleep(self.config.retry_interval)
        except WebDriverException as e:
            logging.error(f"页面刷新失败: {e}")
            self.restart_driver()

    def restart_driver(self):
        """重启WebDriver"""
        try:
            if self.driver:
                self.driver.quit()
            self.setup_driver()
        except WebDriverException as e:
            logging.error(f"重启WebDriver失败: {e}")
            raise

    def run(self):
        """运行主循环"""
        try:
            logging.info("自动回复程序启动")
            while True:
                if msvcrt.kbhit() and msvcrt.getch() == b'\x1b':
                    logging.info("收到退出信号,程序正在终止...")
                    break
                self.handle_new_message()
                # 继续检测新消息并回复
                while True:
                    try:
                        # 检查消息元素是否存在,存在则获取消息内容并回复
                        message_element = self.wait.until(
                            EC.presence_of_element_located(
                                (By.XPATH, "//pre[contains(@class, 'js_message_plain ng-binding')]")
                            )
                        )
                        message_content = message_element.text
                        response = self.get_api_response(message_content)
                        if response:
                            self.send_message(response)
                    except TimeoutException:
                        # 如果没有新消息,退出内层循环
                        break
                    except Exception as e:
                        logging.error(f"处理消息时出错: {e}")
                        self.handle_error()
                        break
        except KeyboardInterrupt:
            logging.info("程序被手动中断")
        finally:
            if self.driver:
                self.driver.quit()
            logging.info("程序已终止")

def main():
    try:
        config = Config.load_from_file()
        auto_reply = WeChatAutoReply(config)
        auto_reply.run()
    except Exception as e:
        logging.critical(f"程序发生致命错误: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值