将Jsoup请求得到的Document中的相对路径转换为绝对路径

在后端开发时经常在HTML页面使用相对路径,然而这个对于爬虫来说有时候却很难受,虽然Jsoup提供了.attr("abs:href")用来来获取绝对路径,但还是不够方便。

在HTML中hrefsrc是这两个属性是用来填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中的相对路径转换为绝对路径

赞 (0) 打赏

回复 Kagura点击这里取消回复。

9+1=

  1. Kagura

    2018-11-08更新,增强对伪协议的支持。

    回复

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏