Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript-Java-Selenium以编程方式获取HTML元素的目标URL_Javascript_Java_Selenium - Fatal编程技术网

使用JavaScript-Java-Selenium以编程方式获取HTML元素的目标URL

使用JavaScript-Java-Selenium以编程方式获取HTML元素的目标URL,javascript,java,selenium,Javascript,Java,Selenium,有一个页面到处都有很多链接,但我无法获取目标URL,因为代码中似乎没有网址,代码如下所示: <li> <a href="javascript:void(0)"> <span title="Text">Text</span> </a> </li> 有大量混乱的代码。我最好的猜测是,它可能是从微服务动态加载URL 有没有一种方法可以通过编程获得元素的

有一个页面到处都有很多链接,但我无法获取目标URL,因为代码中似乎没有网址,代码如下所示:

<li>
    <a href="javascript:void(0)">
        <span title="Text">Text</span>
    </a>
</li>
  • 有大量混乱的代码。我最好的猜测是,它可能是从微服务动态加载URL

    有没有一种方法可以通过编程获得元素的目标URL,而无需导航到链接?我正在尝试将JavaScript/Selenium与Java结合使用


    我在想,通过触发
    onclick
    事件并在重定向之前的某个点获取URL,这可能是可行的。

    我解决了以下问题:

  • 使用JavaScript代码段重新定义浏览器的
    窗口
    对象的
    open()
    方法以获取目标URL,将其存储在全局上下文中并防止重定向
  • 触发单击HTML链接元素以运行底层XMLHttpRequest调用
  • 使用JavaScript的
    clearInterval()
    和Java的
    executeAsyncScript()
    方法,监视全局变量,直到其值被设置为止(值由单击元素后的
    window.open()
    方法设置)
  • 因为我使用的是ChromeDriver,下面的示例将在Google Chrome上运行

    import java.io.IOException;
    import org.openqa.selenium.By;
    import org.openqa.selenium.ElementNotInteractableException;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeOptions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    public class DeadLinkTest {
    
        private static WebDriver driver;
        private static WebDriverWait wait;
        private static JavascriptExecutor js;
        
        private static String driverAbsolutePath = "/chromedriver.exe";
        private static String profileDirectory = "/myprofile";
        //Look for a webpage that actually has elements like <a href='javascript:void(0);'> that causes redirection
        private static String starterUrl = "https://www.google.com/";
    
        //XPath for an element like <a href='javascript:void(0);'> 
        private static final String DEAD_LINKS_XPATH = "//a[starts-with(translate(normalize-space(@href),' ',''),'javascript:void')]";
        private static final String CLICK_ELEMENT_JS_CODE = "arguments[0].click();";
        private static final String DOCUMENT_READY_JS_CODE = "return document.readyState;";
        private static final String LINK_RESOURCE_URL_VAR_NAME = "window.redirectionUrl"; //global variable name
        private static final String PREPARE_BROWSER_FOR_URL_EXTRACTION_JS_CODE =
                "window.windowOpen = window.open;" + //backup original function
                "window.isRedirectionEnabled = false;" + //turn on/off redirection via global variable
                LINK_RESOURCE_URL_VAR_NAME + " = null;" + 
                "window.open = function() {" + //redifine open() method
                "    " + LINK_RESOURCE_URL_VAR_NAME + " = arguments[0];" + //put link's url into global variable
                "    if(window.isRedirectionEnabled) {" + 
                "        windowOpen.apply(this, arguments);" + 
                "    }" + 
                "};";
        private static final String GET_LINK_RESOURCE_URL_JS_CODE =
                "(function(seleniumCallback){" + //IIFE that recieves selenium's callback function from executeAsyncScript() method
                "    let intervalId = setInterval(function(){" + 
                "        if(" + LINK_RESOURCE_URL_VAR_NAME + ") {" + //check if global variable is still null
                "            clearInterval(intervalId);" + 
                "            let urlString = " + LINK_RESOURCE_URL_VAR_NAME + ";" + 
                "            " + LINK_RESOURCE_URL_VAR_NAME + " = null;" + //set global variable to default state
                "            seleniumCallback(urlString);" + //Send back the url to Java
                "        }" + 
                "    },0);" + 
                "}(arguments[0]));";
    
        public static ChromeDriver createChromeDriver() {
            ChromeOptions options = new ChromeOptions();
            options.addArguments("--user-data-dir=" + profileDirectory + "/AppData/Local/Google/Chrome/User Data/Profile 2");
            //options.addArguments("--profile-directory=Profile 2");
            options.addArguments("--start-maximized");
            //options.addArguments("--disable-extensions");
            //options.addArguments("--no-sandbox");
            System.setProperty("webdriver.chrome.driver", driverAbsolutePath);
            return new ChromeDriver(options);
        }
    
        public static void main(String[] args) throws IOException {
    
            driver = createChromeDriver();
            wait = new WebDriverWait(driver, 30);
            js = (JavascriptExecutor) driver;
            try {
                driver.manage().window().maximize();
                driver.get(starterUrl);
                wait.until(webDriver -> js.executeScript(DOCUMENT_READY_JS_CODE).toString().equals("complete")); //Checks that page is loaded
                
                js.executeScript(PREPARE_BROWSER_FOR_URL_EXTRACTION_JS_CODE); //Avoids redirection and prepares global variable
                WebElement deadLink = driver.findElement(By.xpath(DEAD_LINKS_XPATH));
                try {
                    deadLink.click(); //Puts the link url into browser's global variable. See PREPARE_BROWSER_FOR_URL_EXTRACTION_JS_CODE
                } catch (ElementNotInteractableException e) {
                    js.executeScript(CLICK_ELEMENT_JS_CODE, deadLink); //In case element is not clickable
                }
                String linkUrl = (String) js.executeAsyncScript(GET_LINK_RESOURCE_URL_JS_CODE);
                System.out.println(String.format("TARGET URL: %s", linkUrl));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //driver.quit();
            }
        }
    }
    
    import java.io.IOException;
    导入org.openqa.selenium.By;
    导入org.openqa.selenium.elementNotInteractiableException;
    导入org.openqa.selenium.JavascriptExecutor;
    导入org.openqa.selenium.WebDriver;
    导入org.openqa.selenium.WebElement;
    导入org.openqa.selenium.chrome.ChromeDriver;
    导入org.openqa.selenium.chrome.ChromeOptions;
    导入org.openqa.selenium.support.ui.WebDriverWait;
    公共类死链接测试{
    私有静态WebDriver;
    私有静态WebDriverWait等待;
    私有静态JavascriptExecutor js;
    私有静态字符串驱动器RABSolutePath=“/chromedriver.exe”;
    私有静态字符串profileDirectory=“/myprofile”;
    //寻找一个网页,实际上有这样的元素,导致重定向
    专用静态字符串启动器URL=”https://www.google.com/";
    //元素的XPath,如
    私有静态最终字符串DEAD_LINKS_XPATH=“//a[以(translate(规范化空格(@href),“”,,'javascript:void')开头]”;
    私有静态最终字符串CLICK_ELEMENT_JS_CODE=“arguments[0]。CLICK();”;
    私有静态最终字符串DOCUMENT_READY_JS_CODE=“return DOCUMENT.readyState;”;
    私有静态最终字符串链接\u RESOURCE\u URL\u VAR\u NAME=“window.redirectionUrl”;//全局变量名
    私有静态最终字符串为URL提取准备浏览器代码=
    “window.windowOpen=window.open;”+//备份原始函数
    “window.isRedirectionEnabled=false;”+//通过全局变量打开/关闭重定向
    链接资源URL变量名称+“=null;”+
    window.open=function(){“+//redifine open()方法
    “+LINK\u RESOURCE\u URL\u VAR\u NAME+”=参数[0];”++//将链接的URL放入全局变量
    “如果(window.isRedirectionEnabled){”+
    windowOpen.apply(这个,参数);“+
    "    }" + 
    "};";
    私有静态最终字符串GET\u LINK\u RESOURCE\u URL\u JS\u代码=
    “(函数(seleniumCallback){”+//IIFE,它从executeAsyncScript()方法接收selenium的回调函数
    “let intervalId=setInterval(函数(){”+
    “如果(“+LINK\u RESOURCE\u URL\u VAR\u NAME+”{”+//检查全局变量是否仍然为空
    “clearInterval(intervalId);”+
    “let urlString=“+LINK_RESOURCE_URL_VAR_NAME+”;”+
    “+LINK\u RESOURCE\u URL\u VAR\u NAME+”=null;“+//将全局变量设置为默认状态
    “seleniumCallback(urlString);”+//将url发送回Java
    "        }" + 
    "    },0);" + 
    “}(参数[0]);”;
    公共静态ChromeDriver CreateCromeDriver(){
    ChromeOptions选项=新的ChromeOptions();
    options.addArguments(“--user data dir=“+profileDirectory+”/AppData/Local/Google/Chrome/user data/profile2”);
    //options.addArguments(“--profile directory=profile 2”);
    options.addArguments(“--start maximized”);
    //options.addArguments(“--disable extensions”);
    //options.addArguments(“--no sandbox”);
    System.setProperty(“webdriver.chrome.driver”,driverAbsolutePath);
    返回新的ChromeDriver(选项);
    }
    公共静态void main(字符串[]args)引发IOException{
    driver=createChromeDriver();
    等待=新的WebDriverWait(驱动程序,30);
    js=(JavascriptExecutor)驱动程序;
    试一试{
    driver.manage().window().maximize();
    get(starterUrl);
    等待.until(webDriver->js.executeScript(DOCUMENT_READY_js_CODE).toString().equals(“complete”);//检查页面是否已加载
    js.executeScript(为URL提取准备浏览器代码);//避免重定向并准备全局变量
    WebElement deadLink=driver.findElement(By.xpath(DEAD_LINKS_xpath));
    试一试{
    deadLink.click();//将链接url放入浏览器的全局变量中。有关url提取代码,请参阅准备浏览器
    }捕获(ElementNotInteractiableException e){
    js.executeScript(单击_元素_js_代码,死链接);//如果元素不可单击
    }
    String linkUrl=(String)js.executeAsyncScript(获取链接资源URL代码);
    System.out.println(String.format(“目标URL:%s”,linkUrl));
    }捕获(例外e){
    e、 printStackTrace();
    }最后{
    //driver.quit();
    }
    }
    }