SpringBoot使用jsoup爬取HTML

原文网址:SpringBoot使用jsoup爬取HTML_IT利刃出鞘的博客-CSDN博客

简介

本文介绍SpringBoot--使用jsoup(Java爬虫工具)的方法。

jsoup 是一款 Java 的 HTML 解析器,它提供了一套非常便利的 API,可通过 DOM、CSS 通过类似于 JQuery 的操作方法来取出和操作数据。

jsoup的主要功能

  1. 从一个URL、文件或字符串中解析HTML;
  2. 用DOM和css或类似jquery的selector语法获取Element,然后从从中获取节点属性、文本、html
  3. 对Element的进行操作,包括HTML的值、节点内容的值和设置节点属性的值;

引入依赖

XML 复制代码
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.4</version>
</dependency>

解析Document

Jsoup支持四种方式解析Document,即可以输入四种内容得到一个Document:

  1. 字符串
  2. body片段
  3. URL
  4. 文件

字符串解析示例

字符串中必须包含head和body元素。

java 复制代码
String html = "<html><head><title>First parse</title></head>"
  + "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);

body片段解析

java 复制代码
String html = "<div><p>Lorem ipsum.</p>";
Document doc = Jsoup.parseBodyFragment(html);
// doc 此时为:<body> <p>Lorem ipsum.</p></body>

Element body = doc.body();
System.out.println(body);

从URL解析

java 复制代码
Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();

还可以携带cookie等参数:

java 复制代码
Document doc = Jsoup.connect("http://example.com")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  // 自定义key和value
  .header("Content-Type", "application/json")
  .timeout(3000)
  .post();

从文件解析

java 复制代码
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8");

选择元素

获取数据一共有 2 种方式,分别为 DOM方式、CSS选择器方式。

DOM方式

将HTML解析成一个Document之后,就可以使用类似于DOM的方法进行操作。

java 复制代码
Document doc = Jsoup.connect("http://csdn.com").get();

// 获取带有 href 属性的 a 元素
Elements elements = doc.select("a[href]");

for (Element content : elements) {
    String linkHref = content.attr("href");
    String linkText = content.text();
    System.out.print(linkText + "\t");
    System.out.println(linkHref);
}

说明

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:

查找元素

  1. getElementById(String id):通过id来查找元素
  2. getElementsByTag(String tag):通过标签来查找元素
  3. getElementsByClass(String className):通过类选择器来查找元素
  4. getElementsByAttribute(String key) :通过属性名称来查找元素,例如查找带有href元素的标签。
  5. siblingElements():获取兄弟元素。如果元素没有兄弟元素,则返回一个空列表。
  6. firstElementSibling():获取第一个兄弟元素。
  7. lastElementSibling():获取最后一个兄弟元素。
  8. nextElementSibling():获取下一个兄弟元素。
  9. previousElementSibling():获取上一个兄弟元素。
  10. parent():获取此节点的父节点。
  11. children():获取此节点的所有子节点。
  12. child(int index):获取此节点的指定子节点。

CSS选择器方式

可以使用类似于CSS选择器的语法来查找和操作元素,常用的方法为select(String selector)。

java 复制代码
Document doc = Jsoup.connect("http://csdn.com").get();

// 获取带有 href 属性的 a 元素
Elements elements = doc.select("a[href]");

for (Element content : elements) {
    String linkHref = content.attr("href");
    String linkText = content.text();
    System.out.print(linkText + "\t");
    System.out.println(linkHref);
}

说明

  1. select()方法在Document、Element或Elements对象中都可以使用,而且是上下文相关的,因此可实现指定元素的过滤,或者采用链式访问。
  2. select() 方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。

链式访问示例

java 复制代码
Document document = Jsoup.connect(URL).get();

// URL是要爬取页面的链接
Elements elements = document
            .select("div.vsb-box")
            .select("h2[class=cleafix]")
            .select("a[href]");

读取元素

获得元素后,就可以获取元素中的数据。

方法有

  1. attr(String key):获取单个属性值
  2. attributes():获取所有属性值
  3. attr(String key, String value):设置属性值
  4. text():获取文本内容
  5. text(String value):设置文本内容
  6. html():获取元素内的HTML内容
  7. html(String value):设置元素内的HTML内容
  8. outerHtml():获取元素外HTML内容
  9. data():获取数据内容(例如:script和style标签)
  10. id():获得id值(例:<p id="goods">衣服</p>)
  11. className():获得第一个类选择器值
  12. classNames():获得所有的类选择器值
  13. tag():获取元素标签
  14. tagName():获取元素标签名(如:<p>、<div>等)
  15. .hasClass(String className):检查这个元素是否含有一个类选择器(不区分大小写)。
java 复制代码
String html = "<p><a href='http://csdn.com/'><b>example</b></a> link.</p>";
Document doc  = Jsoup.parse(html);

// 查找第一个<a>元素
Element link = doc.select("a").first();

String text  = link.text();
// 输出:example

String href = link.attr("href");
// 输出:http://csdn.com/

String aHtml = link.outerHtml();
// 输出:<b>example</b>

String aOuterHtml = link.outerHtml();
// 输出:<a href='http://csdn.com/'><b>example</b></a>

修改元素

解析了Document对象后,可能想修改其中的某些属性值,把它输出到前台页面或保存到其他地方,jsoup对此提供了一套非常简便的接口(支持链式写法)。

设置属性的值

以下方法针对Element对象操作时,只有一个元素会受到影响。当针对Elements对象进行操作时,会影响到多个元素。

  1. attr(String key, String value):设置标签的属性值。
  2. addClass(String className):增加类选择器选项
  3. removeClass(String className):删除对应的类选择器
java 复制代码
Document doc = Jsoup.connect("http://csdn.com").get();

Elements elements = doc.getElementsByClass("text");
// 复数,Elements

Element element = elements.first();
// 单数,Element


elements.attr("name","goods");
// 复数对象,所有 class="text" 的元素都将受到影响

element.attr("name","shop")
        .addClass("red");
// 单数对象,只有一个元素会受到影响(链式写法)

修改元素的HTML内容

  1. html(String value):这个方法将先清除元素中的HTML内容,然后用传入的HTML代替。
  2. prepend(String value):在元素前添加html内容。
  3. append(String value):在元素后添加html内容。
  4. wrap(String value):对元素包裹一个外部HTML内容,将元素置于新增的内容中间。
java 复制代码
Document doc = Jsoup.connect("http://csdn.com").get();

Element div = doc.select("div").first();
div.html("<p>csdn</p>");
div.prepend("<p>a</p>");
div.append("<p>good</p>");
// 输出:<div"> <p>a</p> <p>csdn</p> <p>good</p> </div>

Element span = doc.select("span").first();
span.wrap("<li><a href='...'></a></li>");
// 输出: <li><a href="..."> <span>csdn</span> </a></li>

修改元素的文本内容

对于传入的文本,如果含有像 <, > 等这样的字符,将以文本处理,而非HTML。

  1. text(String text) :清除元素内部的HTML内容,然后用提供的文本代替。
  2. prepend(String first):在元素后添加文本节点。
  3. Element.append(String last):在元素前添加文本节点。
java 复制代码
Element div = doc.select("div").first();
 // <div></div>

div.text(" one "); 
div.prepend(" two ");
div.append(" three ");
// 输出: <div> two one three </div>

获得完整响应(状态码等)

java 复制代码
// 获得响应对象
Connection.Response response = Jsoup.connect("http://csdn.com").execute();
int code = response.statusCode();

// 输出状态码:200
System.out.println(code);
相关推荐
AI多Agent协作实战派2 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit2 小时前
Java+Ai+vue
java·spring·maven
qq_2518364572 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive2 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿2 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
曹牧2 小时前
Eclipse 批量文本替换
java·ide·eclipse
程序员清风2 小时前
OpenAI官方发布最新提示词技巧!
java·后端·面试
一只枫林2 小时前
MySQL内、外连接知识点汇总
java·前端·数据库
梅头脑2 小时前
写了3年CRUD,volatile和synchronized的区别还是答不清——直到我画出了这张三性两锁边界图
java
暮暮祈安2 小时前
Celery 新手入门指南
java·数据库·python·flask·httpx