使用JavaScript-Java-Selenium以编程方式获取HTML元素的目标URL
有一个页面到处都有很多链接,但我无法获取目标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 有没有一种方法可以通过编程获得元素的
<li>
<a href="javascript:void(0)">
<span title="Text">Text</span>
</a>
</li>
有大量混乱的代码。我最好的猜测是,它可能是从微服务动态加载URL
有没有一种方法可以通过编程获得元素的目标URL,而无需导航到链接?我正在尝试将JavaScript/Selenium与Java结合使用
我在想,通过触发
onclick
事件并在重定向之前的某个点获取URL,这可能是可行的。我解决了以下问题:
窗口
对象的open()
方法以获取目标URL,将其存储在全局上下文中并防止重定向李>
clearInterval()
和Java的executeAsyncScript()
方法,监视全局变量,直到其值被设置为止(值由单击元素后的window.open()
方法设置)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();
}
}
}