使用Java Selenium操作Facebook发帖时无法点击对应功能按钮求助
Selenium操作Facebook发帖功能修复方案
你现有代码跑不通有几个硬伤:
- 使用的XPath带
mount_0_0_08这类动态生成的随机id前缀,每次页面刷新、账号切换、Facebook前端版本迭代都会变化,属于极不稳定的定位方式,大概率匹配不到目标元素 - 定位发帖输入框时只写了选择器,没有把找到的元素传给点击方法,调用
Act.click()时没指定目标元素,默认会点击鼠标当前停留的页面位置,根本激活不了输入框 - 登录后弹出的通知授权、新手指引类弹窗是Facebook自定义的前端DOM弹窗,不是浏览器原生alert组件,你调用
switchTo().alert()会直接抛出NoAlertPresentException,代码直接中断 - 现有代码完全没实现「上传照片/视频」按钮的定位、点击、文件上传逻辑,自然完成不了图文发帖的需求
下面是调整后可正常运行的代码:
package good; import org.openqa.selenium.WebDriver; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import java.util.concurrent.TimeUnit; public class HareKrishna { public static void main (String []args ) throws InterruptedException { ChromeOptions options = new ChromeOptions(); options.addArguments("--disable-notifications"); // 注意chromedriver路径不要带多余空格,原路径里"Automation Tools "的空格容易触发路径识别错误 System.setProperty("webdriver.chrome.driver","/home/gt8201/AjaySingh/AutomationTools/chromedriver_linux64/chromedriver_linux64(1)/chromedriver"); WebDriver driver = new ChromeDriver(options); driver.manage().window().maximize(); // 隐式等待全局设置一次即可,不用重复声明 driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS); driver.get("https://www.facebook.com/"); // 账号登录逻辑 driver.findElement(By.name("email")).sendKeys("你的实际登录账号"); driver.findElement(By.id("pass")).sendKeys("你的实际登录密码"); driver.findElement(By.name("login")).click(); Thread.sleep(8000); // 处理登录后可能弹出的自定义弹窗,这类弹窗不是原生alert,直接找关闭按钮点击即可 try{ WebElement closePop = driver.findElement(By.xpath("//div[@aria-label='关闭' and @role='button']")); if(closePop.isDisplayed()) closePop.click(); }catch (Exception e){ // 没有弹窗就直接执行后续逻辑,不用额外处理 } // 用固定的aria-label属性定位发帖入口,不要用带动态id的绝对路径XPath WebElement postEntry = driver.findElement(By.xpath("//div[@aria-label='发帖子,说说你在想什么?' and @role='button']")); postEntry.click(); Thread.sleep(2000); // 定位编辑区输入发帖文本 WebElement editArea = driver.findElement(By.xpath("//div[@role='dialog']//div[@contenteditable='true']")); editArea.sendKeys("Hare krishna"); // 点击「照片/视频」上传按钮,同样用固定属性定位,不受动态id影响 WebElement uploadEntry = driver.findElement(By.xpath("//div[@aria-label='照片/视频' and @role='button']")); uploadEntry.click(); Thread.sleep(1000); // *文件上传直接定位隐藏的input[type=file]元素传入本地文件路径即可,不用模拟系统弹窗选择操作,稳定性最高* WebElement fileInput = driver.findElement(By.xpath("//input[@type='file' and @accept='image/*,image/heif,image/heic,video/*,video/mp4,video/x-m4v,video/x-matroska,.mkv']")); fileInput.sendKeys("待上传图片/视频的本地绝对路径"); Thread.sleep(3000); // 点击发布按钮完成发帖 WebElement submitBtn = driver.findElement(By.xpath("//div[@role='dialog']//div[@aria-label='发帖' and @role='button']")); submitBtn.click(); // 等待发帖完成后再关闭浏览器,时间可以根据自己的网络情况调整 Thread.sleep(5000); driver.quit(); } }
几个实操注意点:
- 绝对不要直接复制浏览器开发者工具生成的全路径XPath,Facebook前端的DOM id基本都是动态生成的,优先用
aria-label、role、标签属性这类固定特征定位元素,稳定性会高很多 - 原代码里的
driver.navigate().forward()在登录流程里完全多余,直接删掉即可,登录按钮点击后页面会自动跳转 - 如果页面加载慢,可以适当调大Thread.sleep的等待时长,等对应元素加载完成再操作,避免出现元素找不到的报错
- 如果Facebook界面语言不是中文,把XPath里对应的中文文案换成你界面上显示的对应语言文案就行,定位逻辑不用改
内容的提问来源于stack exchange,提问作者Bug Hunter
相关产品推荐
相关产品推荐

