在后端开发时经常在HTML页面使用相对路径,然而这个对于爬虫来说有时候却很难受,虽然Jsoup提供了.attr("abs:href")
用来来获取绝对路径,但还是不够方便。
在HTML中href
跟src
是这两个属性是用来填url的,也是我们需要处理的地方,相对路径一般是/
,./
,../
三种形式开头,所以我们要选出所有带以/
,./
,../
开头的href或src属性的元素,这个操作可以浓缩成一个cssSelector:[src^=./],[src^=../],[src^=/]:not([src^=//]),[src^=/]:not([src^=//]),[href^=./],[href^=../],[href^=/]:not([href^=//]),[href^=/]:not([href^=//])
,虽然看着有点长,但并不复杂。
但是还有一些特殊情况不是以上三种开头方式,比如开源中国首页部分图片链接直接是字母开头。所以还是用[src],[href]
选出所有元素遍历比较安全。
完整代码如下:
package me.kagura.util; import org.jsoup.helper.Validate; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class JJsoupUtil { /** * 将document中所有相对路径的href跟src转换成绝对路径,兼容伪协议 * * @param document * @return */ public static Document convertToAbsUrlDocument(Document document) { Validate.notEmpty(document.baseUri(), "document.baseUri() must not be empty"); Elements relativePathElements = document.select("[src],[href]"); for (Element element : relativePathElements) { if (element.hasAttr("href")) { String href = element.attr("href"); if (!href.matches("^.*:[\\d\\D]*") && !href.equals("#")) { element.attr("href", element.attr("abs:href")); } } if (element.hasAttr("src")) { String src = element.attr("src"); if (!src.matches("^.*:[\\d\\D]*")) { element.attr("src", element.attr("abs:src")); } } } return document; } }
SpringBoot环境建议直接引入jjsoup-spring-boot-starter
即可使用
<dependency> <groupId>me.kagura</groupId> <artifactId>jjsoup-spring-boot-starter</artifactId> <version>0.1.8</version> </dependency>
未经允许不得转载:鹞之神乐 » 将Jsoup请求得到的Document中的相对路径转换为绝对路径
2018-11-08更新,增强对伪协议的支持。