JSoup
jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM、CSS 以及类似于 JQuery 的操作方法来取出和操作数据。官方网站为 jsoup.org 。
JSoup 功能
使用 JSoup,我们能够:
从一个URL,文件或字符串中解析HTML;
使用DOM或CSS选择器来查找、取出数据;
可操作HTML元素、属性、文本;
JSoup Mavven 依赖
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.14.1</version></dependency>
JSoup类
JSoup类通过其静态方法为 jsoup 函数提供了核心公共访问点。 例如,clean()方法清理 HTML 代码,connect()方法创建与 URL 的连接,或者parse()方法解析 HTML 内容。
JSoup 解析 HTML 字符串
package com.lyq.jsoup.example;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;/** * @author : [LiuYanQiang] * @version : [v1.0] * @className : ParseHTML * @description : [JSoup 解析 HTML 字符串] * @createTime : [2022/3/1 15:20] * @updateUser : [LiuYanQiang] * @updateTime : [2022/3/1 15:20] * @updateRemark : [描述说明本次修改内容] */public class ParseHTML { public static void main(String[] args) { // HTML 字符串并输出其标题和正文内容 String htmlStr = "<html><head><title>测试阿巴阿巴</title></head><body><div class=\"ans-cc\">\n" + "<h2 style=\"white-space: normal;\"><span style=\"font-size: 20px; text-indent: 2em; font-family: 微软雅黑, "Microsoft YaHei";\">研究与挑战:吴欣明老师开播啦,时间:1min</span></h2><p style=\"white-space: normal;\"><span style=\"font-size: 22px;\"> <span style=\"font-size: 18px;\">在信息技术和移动互联网高速发展的今天,给我们提供了全新的学习方式。对吴老师而言,是一次非常有趣的尝试,也是一个难得的探险机会</span></span><span style=\"text-indent: 2em;\">!好在有同学们和我一起,开始这个有趣而充满变数的学习旅程。</span></p><p style=\"white-space: normal;\"><span style=\"text-indent: 2em;\"> 我非常的期待,这个旅程将给同学们带来怎样挑战和收获?</span></p><p><iframe frameborder=\"0\" scrolling=\"no\" class=\"ans-module ans-insertlive-module\" module=\"insertlive\" data=\"{"courseid":222719212,"userId":"84555248","title":"\\u5434\\u6b23\\u660e\\u8001\\u5e08\\u76f4\\u64ad\\u95f4","live":true,"liveId":7000120423895093,"vdoid":"vdoid9250725UzP48R","streamName":"LIVENEW5i77mG6svdoid9250725UzP48R","fid":"1606","isYunShi":"0","mid":"12426056900531645004077510","_jobid":"live-7000120423895093","jobid":"live-7000120423895093"}\"></iframe><br/></p><p><span style=\"font-size: 10px;\">制作人:王倩;审校人:郑天娇</span></p>\n" + "</div></body></html>"; //解析 HTML 数据,使用Jsoup的parse()方法,解析 HTML 字符串。 该方法返回一个 HTML 文档 Document doc = Jsoup.parse(htmlStr); //文档的title()方法获取文档的title元素的字符串内容 String title = doc.title(); //文档的body()方法返回body元素; 其text()方法获取元素的文本 String text = doc.body().text(); System.out.printf("Title: %s%n", title); System.out.printf("Body: %s", text); }}
JSoup 解析本地 HTML 文件
重载Jsoup.parse()方法,该方法将File对象作为其第一个参数,解析本地HTML文件
package com.lyq.jsoup.example;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.springframework.util.ResourceUtils;import java.io.File;import java.io.IOException;/** * @author : [LiuYanQiang] * @version : [v1.0] * @className : ParseHTMLFile * @description : [JSoup 解析本地 HTML 文件] * @createTime : [2022/3/1 15:38] * @updateUser : [LiuYanQiang] * @updateTime : [2022/3/1 15:38] * @updateRemark : [描述说明本次修改内容] */public class ParseHTMLFile { public static void main(String[] args) throws IOException { //获取resource下的文件 File file = ResourceUtils.getFile("classpath:index.htm"); //解析 HTML 数据,使用Jsoup的parse()方法,解析 HTML 字符串。 该方法返回一个 HTML 文档 Document doc = Jsoup.parse(file, "utf-8"); //使用文档的getElementById()方法,通过元素的 ID 获得元素。 Element elementById = doc.getElementById("ext-gen1043"); //使用元素的text()方法检索标签的文本 System.out.println(elementById.text()); }}
JSoup 读取网站的标题
package com.lyq.jsoup.example;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import java.io.IOException;/** * @author : [LiuYanQiang] * @version : [v1.0] * @className : ParseTitle * @description : [JSoup 读取网站的标题] * @createTime : [2022/3/1 16:22] * @updateUser : [LiuYanQiang] * @updateTime : [2022/3/1 16:22] * @updateRemark : [描述说明本次修改内容] */public class ParseTitle { public static void main(String[] args) throws IOException { //Jsoup 的connect()方法创建到给定 URL 的连接。 get()方法执行 GET 请求并解析结果; 它返回一个 HTML 文档。 String url = "https://www.xxxxx.com/"; Document doc = Jsoup.connect(url).get(); //使用文档的title()方法,我们获得 HTML 文档的标题。 String title = doc.title(); System.out.println(title); }}
JSoup 读取 HTML 源码
package com.lyq.jsoup.example;import org.jsoup.Jsoup;import java.io.IOException;/** * @author : [LiuYanQiang] * @version : [v1.0] * @className : ParseHTMLSource * @description : [JSoup 读取 HTML 源码] * @createTime : [2022/3/1 16:31] * @updateUser : [LiuYanQiang] * @updateTime : [2022/3/1 16:31] * @updateRemark : [描述说明本次修改内容] */public class ParseHTMLSource { public static void main(String[] args) throws IOException { String url = "https://www.xxxxx.com/"; //html()方法返回元素的 HTML; String html = Jsoup.connect(url).get().html(); System.out.println(html); }}
JSoup 获取信息
HTML 文档的元信息提供有关网页的结构化元数据,例如其描述和关键字。
package com.lyq.jsoup.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : ParseMetaInfo
* @description : [JSoup 获取信息]
* @createTime : [2022/3/1 16:35]
* @updateUser : [LiuYanQiang]
* @updateTime : [2022/3/1 16:35]
* @updateRemark : [描述说明本次修改内容]
*/
public class ParseMetaInfo {
public static void main(String[] args) throws IOException {
String url = "https://www.xxxxxx.com/";
Document doc = Jsoup.connect(url).get();
//文档的select()方法查找与给定查询匹配的元素。first()方法返回第一个匹配的元素。 使用attr()方法,获得content属性的值。
String keywords = doc.select("meta[name=keywords]").first().attr("content");
System.out.println(keywords);
}
}
JSoup 解析链接
package com.lyq.jsoup.example;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import java.io.IOException;/** * @author : [LiuYanQiang] * @version : [v1.0] * @className : ParseLink * @description : [JSoup 解析链接] * @createTime : [2022/3/1 16:41] * @updateUser : [LiuYanQiang] * @updateTime : [2022/3/1 16:41] * @updateRemark : [描述说明本次修改内容] */public class ParseLink { public static void main(String[] args) throws IOException { String url = "https://www.xxxxxx.com/"; Document doc = Jsoup.connect(url).get(); //通过select()方法获取所有链接 Elements links = doc.select("a[href]"); for (Element link : links) { System.out.println("link : " + link.attr("href")); System.out.println("text : " + link.text()); } }}
JSoup 携带cookie访问网站解析网页
package com.lyq.jsoup.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.HashMap;
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : getWebPageWithCookies
* @description : [携带cookie解析网页]
* @createTime : [2022/3/1 17:09]
* @updateUser : [LiuYanQiang]
* @updateTime : [2022/3/1 17:09]
* @updateRemark : [描述说明本次修改内容]
*/
public class getWebPageWithCookies {
public static void main(String[] args) throws IOException {
String cookies = "lv=2; fid=1606; _uid=42117097; uf=b2d2c93beefa90dc6074e4b14f0dd87ea3008fa1de4dbc987ff3c7e9fb7452bac273942a12309ab4247b84c509d7c8ddc49d67c0c30ca5047c5a963e85f1109948ac46923c235946fd68be96b6183b1a5922371ecaa84d0d8501e824c178312d6536d5f0aab9a39c; _d=1646126338610; UID=42117097; vc=5FCC1CC4D9E427B0C0C6B6E6DE3B210A; vc2=98E978B29DE0719619162BD3872C53E7; vc3=d8ji65gDz2%2BUsbM%2FOV3Ka8mhvaDFhXg3ajlWoB6uhLMOf0QTpDaumywtHXcKVwnY%2BebsqdBpuwH529EthYpScC1VFLyL%2BYemuy35uksqiuZP3hxR12DDWhYN8UMms2uezF5x4xt9nq2HzQIMxjYS6jsg4DovfKFVZdkzlvGmLsk%3Db9d1529a5a0dd4812b17f69e4ed03430; xxtenc=58e801da8a1c8a0b1dda7299ae3a0a84; DSSTASH_LOG=C_38-UN_1049-US_42117097-T_1646126338611; ";
String url ="https://mooc1.chaoxing.com/knowledge/cards?clazzid=52482552&courseid=222964015&knowledgeid=523860611";
HashMap<String, String> hashMap = cookiesTransform(cookies);
//获取爬取网页的信息
Document doc = Jsoup.connect(url).cookies(hashMap).get();
String text = doc.text();
System.out.println(text);
}
/*
* @version V1.0
* Title: cookiesTransform
* @author LiuYanQiang
* @description 将cookies串转换成键值对的形式
* @createTime 2022/3/1 8:50
* @param [cookies]
* @return java.util.HashMap<java.lang.String,java.lang.String>*/
public static HashMap<String, String> cookiesTransform(String cookies){
HashMap<String, String> cookiesMap = new HashMap<>();
String[] items = cookies.trim().split(";");
for (String item:items) {
cookiesMap.put(item.split("=")[0], item.split("=")[1]);
}
return cookiesMap;
}
}
JSoup 通过CSS选择器解析网页信息
package com.lyq.jsoup.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.IOException;
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : Selector
* @description : [根据CSS选择器解析网页]
* @createTime : [2022/3/1 17:48]
* @updateUser : [LiuYanQiang]
* @updateTime : [2022/3/1 17:48]
* @updateRemark : [描述说明本次修改内容]
*/
public class Selector {
public static void main(String[] args) throws IOException {
//获取resource下的文件
File file = ResourceUtils.getFile("classpath:bilibili.html");
//解析 HTML 数据,使用Jsoup的parse()方法,解析 HTML 字符串。 该方法返回一个 HTML 文档
Document doc = Jsoup.parse(file, "utf-8");
//查询所有a链接
Elements links = doc.select("a[href]");
//查询所有是.jpg结尾的img标签
Elements image = doc.select("img[src$=.jpg]");
//查询所有div下clss为zone-list-box的标签
Element first = doc.select("div.zone-list-box").first();
//查询class为nav-link-item的li标签后面的a便签
Elements select = doc.select("li.nav-link-item>a");
}
}
Jsoup修改DOM树结构
package com.lyq.jsoup.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : modifyHTML
* @description : [Jsoup修改DOM树结构]
* @createTime : [2022/3/1 18:47]
* @updateUser : [LiuYanQiang]
* @updateTime : [2022/3/1 18:47]
* @updateRemark : [描述说明本次修改内容]
*/
public class modifyHTML {
public static void main(String[] args) {
String htmlStr = "<div class=\"ans-cc\" title=\"123\">\n" +
"<h2 style=\"white-space: normal;\">阿巴阿巴阿巴</h2></div>";
Document doc = Jsoup.parse(htmlStr);
System.out.printf("原始元素: %s%n",htmlStr);
//属性存在则修改,没有则添加
Elements el = doc.select("div.ans-cc").attr("title", "阿巴阿巴");
System.out.printf("修改标题后: %s%n",el.toString());
//设置class
Elements el1 = doc.select("div.ans-cc").attr("title", "阿巴阿巴").addClass("test");
System.out.printf("添加class后: %s%n",el1.toString());
}
}
JSoup 遍历DOM元素树的方法
使用标准的DOM方法
- 根据id查找元素: getElementById(String id)
- 根据标签查找元素: getElementsByTag(String tag)
- 根据class查找元素: getElementsByClass(String className)
- 根据属性查找元素: getElementsByAttribute(String key)
- 兄弟遍历方法: siblingElements(), firstElementSibling(), lastElementSibling(); nextElementSibling(), previousElementSibling()
- 层级之间遍历: parent(), children(), child(int index)
这些方法会返回Element或者Elements节点对象,这些对象可以使用下面的方法获取一些属性:
- attr(String key): 获取某个属性值
- attributes(): 获取节点的所有属性
- id(): 获取节点的id
- className(): 获取当前节点的class名称
- classNames(): 获取当前节点的所有class名称
- text(): 获取当前节点的textNode内容
- html(): 获取当前节点的 inner HTML
- outerHtml(): 获取当前节点的 outer HTML
- data(): 获取当前节点的内容,用于script或者style标签等
- tag(): 获取标签
- tagName(): 获取当前节点的标签名称
支持CSS选择器
JSoup可以像xpath一样很方便的定位某个元素,而不用一层一层地遍历DOM树。调用方法如下:
- document.select(String selector): 选择匹配选择器的元素,返回是Elements对象
- document.selectFirst(String selector): 选择匹配选择器的第一个元素,返回是一个Element对象
- element.select(String selector): 也可以直接在Element对象上执行选择方法
Jsoup能够完美的支持CSS的选择器语法,对有前端经验的java开发者来说不用特意去学习XPath的语法。
比如一个XPath: //*[@id=”docs”]/div[1]/h4/a, 可以转成等效的CSS选择器语法: document.select(“#docs > div:eq(1) > h4 > a”).attr(“href”);。
常见的选择器:
- 标签选择(如div): tag
- id选择(#logo): #id
- class选择(.head): .class
- 属性选择([href]): [attribute]
- 属性值选择: [attr=value]
- 属性前缀匹配: [^attr]
- 属性简单正则匹配: [attr^=value], [attr$=value], [attr*=value], [attr~=regex]
另外还支持下面的组合选择器:
- element#id: (div#logo: 选取id为logo的div元素)
- element.class: (div.content: 选择class包括content的div元素)
- element[attr]: (a[href]: 选择包含href的a元素)
- ancestor child: (div p: 选择div元素的所有p后代元素)
- parent > child: (p > span: 选择p元素的直接子元素中的span元素)
- siblingA + siblingB: (div.head + div: 选取div.head的下一个兄弟div元素)
- siblingA ~ siblingX: (h1 ~ p: 选取h1后面的所有p兄弟元素)
- el, el, el: (div.content, div.footer: 同时选取div.content和div.footer)
当然,还支持伪元素选择器:
- :lt(n): (div#logo > li:lt(2): 选择id为logo的div元素的前3个li子元素)
- :gt(n)
- :eq(n)
- :has(selector)
- :not(selector)
- :contains(text)
今天的文章java爬虫——JSoup分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/12743.html