如何用Python+Selenium在WhatsApp Web中选择图片文件发送?
问题:使用Selenium向WhatsApp联系人发送图片时无法选择文件
我想用Python+Selenium给WhatsApp联系人发送文本和图片,文本功能已经实现,但发送图片时卡在文件选择环节。能点击加号、选择“照片和视频”选项,但弹出系统文件选择窗口后,无法将文件路径输入到窗口中选中目标文件。我使用的是Ubuntu系统,手动通过Ctrl+V粘贴路径再回车可以选中文件,之后就能点击发送,但脚本中的输入总是发送到运行脚本的终端或Emacs窗口,而非文件选择窗口。要求必须使用Selenium完成,不能使用WhatsApp API。
现有代码
from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.firefox.service import Service import time import pyautogui service = Service(log_path = "log.log") driver = webdriver.Firefox(service = service) driver.get("https://web.whatsapp.com") print("Scan QR Code, And then Enter") input() print("Logged In") contacts = ["John Doe", "Mary Jane"] text = """This text works""" file_path = "/home/xyz/Downloads/abcdef.jpeg" for contact in contacts: input_box_search = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[4]/div/div[1]/div/div/div[2]/div/div[1]") input_box_search.click() time.sleep(2) for i in contact: input_box_search.send_keys(i) time.sleep(0.05) selected_contact = driver.find_element(By.XPATH, "//span[@title='"+contact+"']") selected_contact.click() inp_xpath = "/html/body/div[1]/div/div/div[5]/div/footer/div[1]/div/span[2]/div/div[2]/div[1]/div/div[1]" input_box = driver.find_element(By.XPATH, inp_xpath) time.sleep(2) input_box.click() for i in text: input_box.send_keys(i) time.sleep(0.05) input_box.send_keys(Keys.ENTER) time.sleep(2) add_sign = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[5]/div/footer/div[1]/div/span[2]/div/div[1]/div[2]/div/div") add_sign.click() time.sleep(1) photo_icon = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[5]/div/footer/div[1]/div/span[2]/div/div[1]/div[2]/div/span/div/ul/div/div[2]/li/div/span") photo_icon.click() ### This one fails. So does keyboard pyautogui.typewrite(file_path) send_icon = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[3]/div[2]/span/div/span/div/div/div[2]/div/div[2]/div[2]/div/div") send_icon.click() driver.quit()
已尝试方案
- 查阅过Stack Overflow相关问题,包括puppeteer、JavaScript、Flutter的实现方案,但均依赖WhatsApp API,不符合需求
- 尝试过
pyautogui.typewrite(file_path)和keyboard.press_and_release(file_path),但按键输入被发送到运行脚本的终端或Emacs窗口,而非文件选择窗口
解决方案
方案1:确保文件选择窗口获得焦点(适配Ubuntu系统)
点击照片图标后,等待系统弹出文件选择窗口,通过pyautogui定位并激活窗口,再输入路径:
# 替换原代码中photo_icon.click()之后的部分 photo_icon.click() # 等待窗口加载完成 time.sleep(2) # 定位Ubuntu文件选择窗口(标题通常为“打开”) windows = pyautogui.getWindowsWithTitle("打开") if windows: windows[0].activate() # 输入文件路径 pyautogui.typewrite(file_path) # 按回车确认选择 pyautogui.press('enter') # 等待文件加载后点击发送 time.sleep(3) send_icon = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[3]/div[2]/span/div/span/div/div/div[2]/div/div[2]/div[2]/div/div") send_icon.click()
方案2:直接使用Selenium文件上传API(更稳定)
WhatsApp Web的文件选择功能本质是隐藏的<input type="file">元素,可直接定位该元素并发送文件路径,绕开系统文件选择窗口:
# 替换原代码中add_sign.click()到send_icon.click()的全部内容 # 定位隐藏的文件上传input元素 file_input = driver.find_element(By.XPATH, "//input[@accept='image/*,video/mp4,video/3gpp,video/quicktime']") # 直接传入文件路径 file_input.send_keys(file_path) # 等待文件加载完成 time.sleep(3) # 点击发送按钮 send_icon = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/div[3]/div[2]/span/div/span/div/div/div[2]/div/div[2]/div[2]/div/div") send_icon.click()
内容的提问来源于stack exchange,提问作者PavoDive
相关产品推荐
相关产品推荐

