为何执行Selenium链接校验代码时出现ClassCastException异常?
问题:网页链接校验时出现java.lang.ClassCastException异常原因分析
在执行网页链接校验代码时遇到了java.lang.ClassCastException异常,请问是什么原因导致的?
异常信息
Exception in thread "main" java.lang.ClassCastException: class sun.net.www.protocol.mailto.MailToURLConnection cannot be cast to class java.net.HttpURLConnection (sun.net.www.protocol.mailto.MailToURLConnection and java.net.HttpURLConnection are in module java.base of loader 'bootstrap')
测试代码
package brokenLinks; import java.io.IOException; import java.net.HttpURLConnection; //import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import io.github.bonigarcia.wdm.WebDriverManager; public class ValidateBrokenLinksTest { public static void main(String[] args) throws IOException { //设置WebDriver驱动 WebDriverManager.chromedriver().setup(); //启动Chrome浏览器驱动 WebDriver driver = new ChromeDriver(); //最大化浏览器窗口 driver.manage().window().maximize(); //加载目标网页 driver.get("https://testerscafe.in/"); //设置隐式等待,等待页面加载 driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)); //获取页面中所有<a>标签元素,存入列表集合 List<WebElement> elements = driver.findElements(By.tagName("a")); //获取链接总数 int size = elements.size(); System.out.println("网页中的链接总数:"+size); //遍历每个链接,获取其href属性值 for(WebElement links : elements) { String link = links.getAttribute("href"); //将链接加载至URL类实例 URL url = new URL(link); //建立连接 HttpURLConnection connection = (HttpURLConnection)(url.openConnection()); connection.connect(); //校验链接有效性 if(connection.getResponseCode()>=400) { System.out.println(link+" ==> 是失效链接"); } else { System.out.println(link+" ==> 是有效链接"); } } //关闭浏览器驱动 driver.quit(); } }
原因分析
页面中的<a>标签不止包含HTTP/HTTPS协议的网页链接,还可能存在mailto:(邮件链接)、tel:(电话链接)这类非HTTP协议的链接。当你对mailto:类型的链接调用url.openConnection()时,返回的是MailToURLConnection对象,这个类和HttpURLConnection没有继承关系,强行做类型转换就会触发ClassCastException。
解决方案
- 过滤非HTTP/HTTPS链接:只处理以
http://或https://开头的链接,跳过其他协议的链接 - 增加空值校验:避免
href属性为空的情况,防止创建URL对象时出错
修改后的代码示例
package brokenLinks; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.time.Duration; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import io.github.bonigarcia.wdm.WebDriverManager; public class ValidateBrokenLinksTest { public static void main(String[] args) throws IOException { WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://testerscafe.in/"); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)); List<WebElement> elements = driver.findElements(By.tagName("a")); int size = elements.size(); System.out.println("网页中的链接总数:"+size); for(WebElement links : elements) { String link = links.getAttribute("href"); // 跳过空链接和非HTTP/HTTPS协议的链接 if(link == null || !link.startsWith("http")) { System.out.println(link+" ==> 非HTTP/HTTPS链接,跳过校验"); continue; } URL url = new URL(link); HttpURLConnection connection = (HttpURLConnection)(url.openConnection()); connection.connect(); if(connection.getResponseCode()>=400) { System.out.println(link+" ==> 是失效链接"); } else { System.out.println(link+" ==> 是有效链接"); } // 关闭连接释放资源 connection.disconnect(); } driver.quit(); } }
内容的提问来源于stack exchange,提问作者M S
相关产品推荐
相关产品推荐

