无需API实现WhatsApp接收自拍、人脸比对及匹配图片回传
问题描述
我正在开发一个Python项目,需求如下:
- 用户通过WhatsApp发送自拍
- 将自拍与我的婚礼图片数据库中的人脸进行比对
- 把包含该用户的所有图片回传给对方
- 要求不使用官方API,采用免费方案
我已经完成了人脸比对的核心代码:
import face_recognition import os import time def load_face_images(source_folder): known_encodings = [] image_paths = [] for filename in os.listdir(source_folder): image_path = os.path.join(source_folder, filename) image = face_recognition.load_image_file(image_path) face_locations = face_recognition.face_locations(image) # Process all detected faces in the image for face_location in face_locations: face_encoding = face_recognition.face_encodings(image, [face_location])[0] known_encodings.append(face_encoding) image_paths.append(image_path) return known_encodings, image_paths def search_person_in_images(target_image, known_encodings, image_paths, tolerance=0.5): target_face_locations = face_recognition.face_locations(target_image) target_face_encodings = face_recognition.face_encodings(target_image, target_face_locations) matching_image_paths = {} for i, face_encoding in enumerate(target_face_encodings): matches = face_recognition.compare_faces(known_encodings, face_encoding, tolerance=tolerance) matching_image_paths[i] = [image_paths[j] for j, match in enumerate(matches) if match] return matching_image_paths start_time = time.time() source_folder = "faces" known_encodings, image_paths = load_face_images(source_folder) target_image_path = "image1.jpeg" target_image = face_recognition.load_image_file(target_image_path) matching_image_paths = search_person_in_images(target_image, known_encodings, image_paths) num_matches = sum(len(paths) for paths in matching_image_paths.values()) print("Number of matching images:", num_matches) end_time = time.time() execution_time = end_time - start_time print("Execution time:", execution_time, "seconds")
现需解决:如何实现自动接收WhatsApp用户发送的图片、完成人脸比对并回传匹配图片?要求用免费方案。
免费实现方案(基于WhatsApp Web自动化)
核心思路是通过Selenium操控WhatsApp Web实现收发图片,结合你已有的人脸比对逻辑完成全流程。
1. 依赖安装
执行以下命令安装所需库:
pip install selenium pillow face_recognition
同时下载与你的Chrome浏览器版本匹配的ChromeDriver,放在项目目录下。
2. 完整整合代码
import time import os import shutil from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException import face_recognition # 保留你已有的人脸比对函数 def load_face_images(source_folder): known_encodings = [] image_paths = [] for filename in os.listdir(source_folder): image_path = os.path.join(source_folder, filename) image = face_recognition.load_image_file(image_path) face_locations = face_recognition.face_locations(image) for face_location in face_locations: face_encoding = face_recognition.face_encodings(image, [face_location])[0] known_encodings.append(face_encoding) image_paths.append(image_path) return known_encodings, image_paths def search_person_in_images(target_image, known_encodings, image_paths, tolerance=0.5): target_face_locations = face_recognition.face_locations(target_image) target_face_encodings = face_recognition.face_encodings(target_image, target_face_locations) matching_image_paths = {} for i, face_encoding in enumerate(target_face_encodings): matches = face_recognition.compare_faces(known_encodings, face_encoding, tolerance=tolerance) matching_image_paths[i] = [image_paths[j] for j, match in enumerate(matches) if match] return matching_image_paths # WhatsApp自动化逻辑 def init_whatsapp_web(driver_path): options = webdriver.ChromeOptions() # 保存会话,避免重复扫码 options.add_argument("user-data-dir=./whatsapp_session") driver = webdriver.Chrome(executable_path=driver_path, options=options) driver.get("https://web.whatsapp.com/") print("请扫码登录WhatsApp Web,登录后按回车继续...") input() return driver def download_latest_image(driver, temp_dir): try: # 获取最新图片消息 image_elements = driver.find_elements(By.XPATH, "//div[@data-testid='message-image']") if not image_elements: return None latest_image = image_elements[-1] latest_image.click() time.sleep(2) # 下载原图 download_btn = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//div[@data-testid='download']")) ) download_btn.click() time.sleep(3) # 移动到临时目录 download_dir = os.path.expanduser("~/Downloads") files = sorted(os.listdir(download_dir), key=lambda x: os.path.getctime(os.path.join(download_dir, x))) latest_file = files[-1] src_path = os.path.join(download_dir, latest_file) dest_path = os.path.join(temp_dir, latest_file) shutil.move(src_path, dest_path) # 关闭预览窗口 close_btn = driver.find_element(By.XPATH, "//div[@data-testid='close']") close_btn.click() time.sleep(1) return dest_path except Exception as e: print(f"下载图片出错: {e}") return None def send_images_to_user(driver, images_paths): try: # 打开附件菜单 attach_btn = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//div[@data-testid='attach-menu']")) ) attach_btn.click() time.sleep(1) # 选择图片并添加 image_input = driver.find_element(By.XPATH, "//input[@accept='image/*,video/mp4,video/3gpp,video/quicktime']") for img_path in images_paths: image_input.send_keys(img_path) time.sleep(2) # 发送图片 send_btn = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//div[@data-testid='send']")) ) send_btn.click() time.sleep(3) except Exception as e: print(f"发送图片出错: {e}") def main(): # 配置参数 driver_path = "./chromedriver" # 替换为你的ChromeDriver路径 wedding_images_folder = "./faces" # 婚礼图片数据库目录 temp_dir = "./temp_images" os.makedirs(temp_dir, exist_ok=True) # 加载人脸编码库 known_encodings, image_paths = load_face_images(wedding_images_folder) print(f"已加载 {len(known_encodings)} 个人脸编码") # 初始化WhatsApp Web driver = init_whatsapp_web(driver_path) try: print("开始监听消息...") while True: # 检查新图片 img_path = download_latest_image(driver, temp_dir) if img_path: print(f"收到新图片: {img_path}") # 人脸比对 target_image = face_recognition.load_image_file(img_path) matching_paths = search_person_in_images(target_image, known_encodings, image_paths) # 去重收集匹配图片 all_matches = list(set([path for paths in matching_paths.values() for path in paths])) if all_matches: print(f"找到 {len(all_matches)} 张匹配图片,正在发送...") send_images_to_user(driver, all_matches) else: print("未找到匹配图片") # 删除临时文件 os.remove(img_path) time.sleep(5) # 每5秒检查一次消息 except KeyboardInterrupt: print("程序终止") finally: driver.quit() shutil.rmtree(temp_dir) if __name__ == "__main__": main()
3. 关键注意事项
- ChromeDriver版本:必须与本地Chrome浏览器版本完全匹配,否则会启动失败。
- 会话保留:第一次扫码登录后,
user-data-dir目录会保存登录状态,后续启动无需重复扫码。 - 反限制机制:WhatsApp Web对自动化操作有检测,避免过于频繁的消息收发,建议调整监听间隔(比如5-10秒)。
- 图片去重:同一张婚礼图片可能包含多个匹配人脸,用
set去重避免重复发送。
内容的提问来源于stack exchange,提问作者eitan
相关产品推荐
相关产品推荐

