我正在使用以下代码“解决”相同的问题。虽然我更喜欢在本地文件系统上运行的 jsoup 函数,但同时我还需要一些东西。该解决方案将文件位置作为 baseURI 发送到解析器,然后将每个相对路径连接到该基础。不幸的是,这意味着我失去了 HTML 的“../”的嵌套功能,jsoup 通常使用其内置函数来处理。此外,我永远无法像内置函数那样确定结果。
幸运的是,我主要将它用于 JUnit 测试,它应该会给我的生产代码增加一些小风险。上下文是我建立了一个本地“互联网”来测试离线爬行。我通过在我的 JUnit 测试类中向其发送本地 HTML 文件来创建 JSoup 文档:
// From my JUnit Test
String testFileName = "HTMLTest_RelativeReferences.html";
String testFilePath = getClass().getResource(testFileName).getPath();
String testFileBaseURI = testFilePath.replace(testFileName, "");
// ...
// Sends filePath and baseURI to testing class that creates JSoup Doc with:
siteDoc = Jsoup.parse(new File(testFilePath), "UTF-8", testFileBaseURI);
现在我使用 baseURI 创建了我的文档,你和我都认为相对路径应该使用该 baseURI 来创建绝对路径。由于失败了,我对空字符串 abs:refs 运行了一个简单的测试并连接我自己的 URL。
Elements links = siteDoc.select("a[href]"); // extract link collection
for (Element link : links) { // iterate through links
String linkString = link.attr("abs:href"); // ftr, neither this nor absUrl("href") works
if (linkString.isEmpty()) { // check if returned "" (i.e., the problem at hand)
URLs.add(siteDoc.baseUri() + link.attr("href")); // concatenate baseURI to relative ref
}
else { // for all the properly returned absolute refs
URLs.add(link.attr("abs:href"));
}
}
我所有的 JUnit 测试都继续通过绝对和相对本地引用 - 祝你好运!
我用于参考的 HTML Doc 与代表同一文件夹中其他 HTML 文件的所有 3 个链接:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HTML Test using Relative References</title>
</head>
<body>
<a href="LinkedHTMLFile1.html">Link1</a>
<a href="LinkedHTMLFile2.html">Link2</a>
<a href="LinkedHTMLFile3.html">Link3</a>
</body>
</html>
编辑:我对 jsoup 库的深入研究让我相信我们的本地文件“URL”永远不会工作,因为 jsoup 在其 attr("abs:href") 过程中处理实际 URL 并将通过 MalformedURLs 并返回 "",因为我们是实际上使用本地文件路径而不是真正的 URL。我认为这超出了上述答案的范围,但我想我会提到我的发现。