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

标签 java javascript google-maps selenium navigation

我想点击这个页面的打印按钮:

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

最佳答案

这是我的见解。

首先,您需要等待页面加载才能与 Print 按钮进行交互。最好的方法是使用内置机制:selenium waits - 等待 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();

好的,如果您使用 ChromeDriver 运行它:

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 也无法控制它。所以,不,没有希望。哦,等等!


好的,如果我们超出了 selenium 的范围,让我们使用可以帮助我们单击对话框中的 Print 按钮的工具 - Robot类:

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 - 您需要打印按钮的图像,以便 sikuli 找到它并单击
  • autoit

另见:

关于java - 如何使用 Selenium 单击网页上的打印按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26522739/

相关文章:

java - 是否有一个 Java 集合可以在添加更多项目时删除项目? (一个简单的缓存)

javascript - 谷歌地图 KML 图层初始缩放和中心

javascript - 地理定位真的很慢我做错了什么?

javascript - React native - 对象作为 React 子对象无效(找到 : object with keys {$$typeof, 类型、键、引用、 Prop 、_owner、_store})

javascript - 如何打开带有 base64 PDF 内容的新窗口?

google-maps - Google Maps Solar API : Getting "404 Entity Not Found" for Specific Buildings, 如何检查可用区域?

ios - 在 iOS 上制作 MarkerinfoWindow 动画

java - 示例 WorldWind 应用程序在启动时遇到 AbstractMethodError

java - 当两个泛型参数具有相同的上限时,未经检查的强制转换警告

java - 使用 getter 作为参数调用函数不会保留引用?