Java爬虫jsoup工具类

一、定义

jsoup官网,jsoup是一个用于处理HTML的Java库,它提供了一个非常方便类似于使用DOM,CSS和jQuery的方法的API来提取和操作数据。

jsoup实现WHATWG HTML5规范,并将HTML解析为与现代浏览器相同的DOM。

  • 从URL,文件或字符串中提取并解析HTML
  • 查找和提取数据,使用DOM遍历或CSS选择器
  • 操纵HTML元素,属性和文本
  • 根据安全的白名单清理用户提交的内容,以防止XSS攻击
  • 输出整洁的HTML

jsoup旨在处理发现所有格式有差异的HTML,从原始和验证,到无效的标签,jsoup将创建一个明智的解析树。

二、主要作用

  • DOM:将HTML解析为与现代浏览器相同的DOM,和js中的document对象一样,用getElementById等方法获取元素
  • CSS:利用CSS选择器选择src等属性

三、开源

jsoup是一个根据自由MIT许可证分发的开源项目,源代码可在GitHub获得:http://github.com/jhy/jsoup/

四、jsoup安装

要运行任何jsoup示例,需要先安装好jsoup相关Jar包,安装jsoup主要有三种方法:

  • 通过Maven的pom.xml配置文件
  • 使用jsoup.jar文件
  • Gradle的配置文件

通过Maven的pom.xml文件配置:


  
  org.jsoup
  jsoup
  1.15.3

jsoup是完全自包含的,没有依赖关系。

五、jsoup应用的主要类

然完整的类库中有很多类,但大多数情况下,下面给出3个类是我们需要重点了解的。

5.1 org.jsoup.Jsoup

jsoup类是任何Jsoup程序的入口点,并将提供从各种来源(URL、文件、字符串)加载和解析HTML文档的方法。

5.1.1 从URL加载解析HTML文档

方式一:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.net.URL;

public class Test {
    public static void main(String[] args) throws IOException {
        Document document = Jsoup.parse(new URL("http://www.yiibai.com"), 30000);
        String title = document.title();

        //易百教程™ - 专注于IT教程和实例
        System.out.println(title);
    }
}

方式二:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        Document document = Jsoup.connect("http://www.yiibai.com").get();
        String title = document.title();

        //易百教程™ - 专注于IT教程和实例
        System.out.println(title);
    }
}
5.1.2 从文件加载解析HTML文档
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        Document document = Jsoup.parse( new File( "D:/yibai.html" ) , "utf-8" );
        String title = document.title();

        //易百教程™ - 专注于IT教程和实例
        System.out.println(title);
    }
}

备注:在浏览器中打开http://www.yiibai.com网站,然后ctrl+s将该网站保存到本地yibai.html。

5.1.3 从字符串加载解析HTML文档
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        String html = "易百教程™ - 专注于IT教程和实例"
                + "

Parsed HTML into a doc.

"; Document document = Jsoup.parse(html); String title = document.title(); //易百教程™ - 专注于IT教程和实例 System.out.println(title); } }
5.2 org.jsoup.nodes.Document

该类表示通过jsoup库加载HTML文档。可以使用此类执行适用于整个HTML文档的操作。Element类的重要方法可以参见 http://jsoup.org/apidocs/org/jsoup/nodes/Document.html

5.2.1 DOM

document对象和JavaScript里的document是一个东西,js里能用的方法这里都能调用。

Element element = document.getElementById("J_goodsList");
5.2.2 CSS选择器

下面例子中从HTML提取带a[href] 、src、 link[href]属性的元素,再用这些元素的attr函数提取更精确额内容。

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        Document doc = Jsoup.connect("http://www.yiibai.com").get();
        Elements links = doc.select("a[href]");
        Elements media = doc.select("[src]");
        Elements imports = doc.select("link[href]");

        System.out.println("links size:=" + links.size());
        for (Element link : links) {
            System.out.println(link.attr("abs:href"));
        }

        System.out.println("media size:=" + media.size());
        for (Element src : media) {
            if (src.tagName().equals("img")) {
                System.out.println(src.tagName() + " " + src.attr("abs:src") + " " + src.attr("width"));
            } else {
                System.out.println(src.tagName() + " " + src.attr("abs:src") + " " + src.attr("width"));
            }
        }

        System.out.println("imports size:=" + imports.size());
        for (Element link : imports) {
            System.out.println(link.tagName() + " " + link.attr("abs:href") + " " + link.attr("rel"));
        }
    }
}
5.3 org.jsoup.nodes.Element

HTML元素是由标签名称,属性和子节点组成。 使用Element类,您可以提取数据,遍历节点和操作HTML。Element类的重要方法可参见 http://jsoup.org/apidocs/org/jsoup/nodes/Element.html

六、常用功能

6.1 获取URL的链接

Elements类中可以使用for-each循环遍历元素。Element类提供了attr()和text()方法来返回链接的链接和对应的文本。

Document doc = Jsoup.connect("http://www.yiibai.com").get();  
Elements links = doc.select("a[href]");  
for (Element link : links) {  
    System.out.println("\nlink : " + link.attr("href"));  
    System.out.println("text : " + link.text());  
}
6.2 获取URL的元信息
Document doc = Jsoup.connect("http://www.yiibai.com").get();  
String keywords = doc.select("meta[name=keywords]").first().attr("content");  
System.out.println("Meta keyword : " + keywords);  
String description = doc.select("meta[name=description]").get(0).attr("content");  
System.out.println("Meta description : " + description);
6.3 获取URL的图片
Document doc = Jsoup.connect("http://www.yiibai.com").get();  
Elements images = doc.select("img[src~=.+(.JPEG|.jpeg|.JPG|.jpg|.PNG|.png|.GIF|.gif)$");  
for (Element image : images) {  
    System.out.println("src : " + image.attr("src"));  
    System.out.println("height : " + image.attr("height"));  
    System.out.println("width : " + image.attr("width"));  
    System.out.println("alt : " + image.attr("alt"));  
}
6.4 获取表单参数
Document doc = Jsoup.parse(new File("D:/yibai.html"),"utf-8");  
Element loginform = doc.getElementById("registerform");  

Elements inputElements = loginform.getElementsByTag("input");  
for (Element inputElement : inputElements) {  
    String key = inputElement.attr("name");  
    String value = inputElement.attr("value");  
    System.out.println("Param name: "+key+" \nParam value: "+value);  
}

七、jsoup上传图片到OSS

7.1 OssComponent
@Slf4j
@Component
public class OssComponent {

    @Resource
    private OssConfig ossConfig;

    @Value("${spring.profiles.active}")
    private String active;

    public String uploadByInputStream(InputStream inputStream,
                                      Long memberId, String fileName) {
        String bucketName = getBucketName();

        // /content/{memberId}/{datetime.now.date}/xxxxxxx.jpg
        String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        String objectName = StrUtil.format("content/{}/{}/{}", memberId, date, fileName);

        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
        try {
            PutObjectResult result = ossClient.putObject(bucketName, objectName, inputStream);
            if (StringUtil.isNotEmpty(result.getETag())) {
                String newUrl = StrUtil.format("https://{}.{}/{}",bucketName,ossConfig.getEndpoint(),objectName);
                return newUrl;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    private String getBucketName() {
        if ("prod".equals(active)) {
            return "prod-public";
        } else {
            return "test-public";
        }
    }
}
7.2 OssConfig
@Data
@Component
@ConfigurationProperties(prefix="aliyun-oss")
public class OssConfig {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String roleArn;
    private Long durationSeconds;
    private String bucketName;
}
7.3 loadImage
/**
     * 上传图片到OSS
     *
     * @param originUrl:可访问的待上传图片的全地址
     * @param memberId
     * @return 上传到OSS的新地址
     */
    public String loadImage(String originUrl, Long memberId) {
        try {
            String[] fileNameArray = originUrl.split("/");
            String fileName = fileNameArray[fileNameArray.length - 1];
            if (fileName.contains("?")) {
                fileName = fileName.split("\\?")[0];
            }

            byte[] byteArray = Jsoup.connect(originUrl).validateTLSCertificates(false).ignoreContentType(true).maxBodySize(Integer.MAX_VALUE).execute().bodyAsBytes();

            InputStream inputStream = new ByteArrayInputStream(byteArray);
            return ossComponent.uploadByInputStream(inputStream, memberId, fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

你可能感兴趣的:(Java爬虫jsoup工具类)