有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用Selenium单击网页上的打印按钮

我想单击此页面中的“打印”按钮:

https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en

enter image description here

然后保存PDF

enter image description here

这是单击按钮的代码:

String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";

WebDriver driver = new HtmlUnitDriver();
driver.get(url);

System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());

WebElement element = driver.findElement(By.xpath("//*[@id=\"text-mode-options-header\"]/div/div/div[2]/div[2]/div/button[1]"));
element.click();

System.out.println("Page title is: " + driver.getTitle());
driver.quit();

但我得到了以下错误:

    Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate a node using //*[@id="text-mode-options-header"]/div/div/div[2]/div[2]/div/button[1]
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.43.1', revision: '5163bce', time: '2014-09-10 16:27:58'
Driver info: driver.version: HtmlUnitDriver
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElementByXPath(HtmlUnitDriver.java:1057)
    at org.openqa.selenium.By$ByXPath.findElement(By.java:357)
    at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1575)
    at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1)
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.implicitlyWaitFor(HtmlUnitDriver.java:1251)
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:1572)
    at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:532)
    at com.controlstation.start.Main.main(Main.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

如何使用Selenium实现这一点?还有别的办法吗?谢谢

编辑:

enter image description here


共 (3) 个答案

  1. # 1 楼答案

    为了补充@JoriO发布的内容,在使用Selenium单击该web元素之前,您可以测试它是否存在吗?如果它不存在,在驱动程序后添加一个线程睡眠语句。获取(url)。。。原因是Selenium可能会在驱动程序完成加载页面之前尝试单击。这解决了我在使用Selenium错误“无此类元素异常”时遇到的大多数问题

  2. # 2 楼答案

    以下是我的见解

    首先,您需要等待页面加载,以便与Print按钮交互。最好的方法是使用内置机制:selenium等待——等待Print按钮可点击

    // open print dropdown
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
    
    // click print button
    WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
    printButton.click();
    

    好的,如果使用^{}运行它:

    package com.company;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    
    public class Main {
        public static void main(String[] args) {
            String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";
    
            WebDriver driver = new ChromeDriver();
            driver.get(url);
    
            // open print dropdown
            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
    
            // click print button
            WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
            printButton.click();
    
            // now what? 
        }
    }
    

    您将看到Chrome打印预览对话框,不幸的是,它超出了selenium的范围:

    enter image description here

    但是,有一个希望,如果你检查一下可用的Chrome arguments,你会发现有一个相关的:

    disable-print-preview - Disables print preview (For testing, and for users who don't like us. :[ )

    好的,让我们试试:

    ChromeOptions options = new ChromeOptions();
    options.addArguments(" disable-print-preview");
    
    WebDriver driver = new ChromeDriver(options);
    driver.get(url);
    

    现在,将显示一个系统打印对话框:

    enter image description here

    硒也不能控制它。所以,不,没有希望。哦,等等


    好的,如果我们超出了selenium的范围,那么让我们使用一些工具来帮助我们单击对话框-^{}类中的Print按钮:

    This class is used to generate native system input events for the purposes of test automation, self-running demos, and other applications where control of the mouse and keyboard is needed.

    我们将初始化Robot,并在打印对话框出现时发送Enter键:

    package com.company;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    import java.awt.*;
    import java.awt.event.KeyEvent;
    
    
    public class Main {
        public static void main(String[] args) throws AWTException, InterruptedException {
            String url = "https://www.google.com/maps/dir/40.4515849,-3.6903752/41.380896,2.1228198/@40.4515849,-3.6903752/am=t/?hl=en";
    
            Robot r = new Robot();
            r.delay(1000);
    
            WebDriver driver = new ChromeDriver();
            driver.get(url);
    
            // open print dropdown
            WebDriverWait wait = new WebDriverWait(driver, 10);
            wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.print-button"))).click();
    
            // click print button
            WebElement printButton = driver.findElement(By.cssSelector("button.print-popup-button"));
            printButton.click();
    
            Thread.sleep(2000);
    
            r.keyPress(KeyEvent.VK_ENTER);
            r.keyRelease(KeyEvent.VK_ENTER);
        }
    }
    

    其他选项包括:

    • ^{}您需要打印按钮的图像,以便sikuli找到它并单击
    • ^{}

    另见:

  3. # 3 楼答案

    通过这种方式,您可以单击Print including maps-选项(抱歉,它是C#):

    Actions builder = new Actions(Driver);
    builder.MoveToElement(Driver.FindElement(By.ClassName("print-button"))).Click()
           .MoveToElement(Driver.FindElements(By.ClassName("print-popup-button"))[0]).Click().Build().Perform();            
    

    但是!在你的问题中,你有一张Chrome打印预览窗口的图片,我想你的代码正在使用的HtmlUnitDriver无法提供。你总是可以用chromedriver运行测试,但打印预览似乎超出了selenium的范围,也就是说,你不能用webdriver控制它。据我所知,firefox中出现的系统打印对话框也是如此。如果HtmlUnitDriver在这种情况下的行为不同,那么您会没事的,但我担心您将在这里面临一个问题