Java爬虫之 Jsoup 使用

1,444 阅读5分钟

sffff.jpg


什么是 Jsoup

Jsoup :是处理 Html网页的 Java 工具库。针对 Html 5 DOM方法和 CSS选择器提供了非常方便的API,可以便捷的获取 URL 返回内容的提取和相关数据操作。

Jsoup 主要实现一下功能:

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

Jsoup使用

引入 Jsoup 依赖引入,历史版本

 <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
 <dependency>
     <groupId>org.jsoup</groupId>
     <artifactId>jsoup</artifactId>
     <version>1.13.1</version>
 </dependency>

加载 Html 文档方式

  • URL 方式加载
 // 创建URL连接   设置 超时时间、header、cookie等相关信息
 Connection connection = Jsoup.connect("http://fundf10.eastmoney.com/jbgk_009265.html")
                 .timeout(3000)
                 .header("key","value")
                 .cookie("c1","****");
 //  get请求
 Document docGetReq = connection.get();
 // post 请求时需要通过 postDataCharset()方法设置传递参数信息
 Document docPostReq = connection.post();
  • 文件方式加载
 // 加载Html文件
 File f = new File("1.html");
 Document doc = Jsoup.parse(f, "UTF-8");
 Element body = doc.body();
  • String 字符串方式加载
 // 建议采用前两种方式进行Html网页的解析
 String html = "<html><head><title>First parse</title></head>"
   + "<body><p>Parsed HTML into a doc.</p></body></html>";
 Document doc = Jsoup.parse(html);

Html 文档分析

对 Html 进行分析时,一般是将获取到的信息转换为 Document (文档) 。 Html 标签存在严格的层次对应关系,索引解析时是按照这个层级进行层层解析。可以根据某一层次的定位,获取当前层次对应的上一层级或者下一层级关系,方便快速的获取到 Document 中的层级中的 元素信息。

通过DOM进行数据提取

 File input = new File("/tmp/input.html");
 Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
 ​
 // 根据 id 获取文档中的内容信息
 Element content = doc.getElementById("content");
 // 获取 'a' 标签中的元素信息
 Elements links = content.getElementsByTag("a");
 for (Element link : links) {
     // 获取超链接路径
   String linkHref = link.attr("href");
     // 获取文本信息
   String linkText = link.text();
 }

寻找元素

寻找元素

  • getElementById(String id) :根据标签中的 id 获取元素,如果存在多个id值一样,则在不同的地方解析时将会获取到当前节点下最近 id 的结果值

  • getElementsByTag(String tag): 根据 Html 中的标签获取元素

  • getElementsByClass(String className) : 根据 class 名称获取元素

  • getElementsByAttribute(String key) :根据具体属性的 key 获取元素

  • 元素相邻层级(兄弟层级)

    • siblingElements() :同层级元素列表
    • firstElementSibling():同层级的第一个元素节点
    • lastElementSibling():同层级的最后一个元素节点
    • nextElementSibling():当前层级下的同一层级中的所有同一层级的元素列表,如AB(1,2,3)C中当前层级为A,获取的是B层级中 1,2,3 的层级列表
    • previousElementSibling():跟 nextElementSibling() 类似,如AB(1,2,3)C中当前层级为 1,获取的是1层级的上一个层级的A,B,C 层级列表

元素数据获取

  • attr(String key) :获取属性为key的值
  • attr(String key, String value):修改属性key的值为value
  • attributes():获取所有属性
  • text():获取标签的文本内容 , text(String value) : 设置文本内容
  • ownText() :获取当前节点的文本内容
  • tag() :获取标签的tag名称, tagName(String key):修改标签的名称为key
  • html() html(String value):同上
  • outerHtml() : 获取 外部Html 值

操作Html 和文本(在现有的Html 文件中追加部分内容信息)

  • append(String html), prepend(String html)
  • appendText(String text), prependText(String text)
  • appendElement(String tagName), prependElement(String tagName)
  • html(String value)

通过 Selector 进行数据提取

通过 Selector 选择器,可以方便的从Html 中的 CSS 或类似 Jquery 的选择器语法中查找和操作元素。

 File input = new File("/tmp/input.html");
 Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
 ​
 Elements links = doc.select("a[href]"); // a with href
 Elements pngs = doc.select("img[src$=.png]");
 // img with src ending .png
 ​
 Element masthead = doc.select("div.masthead").first();
 // div with class=masthead
 ​
 Elements resultLinks = doc.select("h3.r > a"); // direct a after h3

选择器概述

  • tagname: 按标签查找元素,例如 a
  • ns|tag: 在命名空间中通过标签fb|name查找<fb:name>元素,例如查找元素
  • #id: 通过 ID 查找元素,例如 #logo
  • .class: 按类名查找元素,例如 .masthead
  • [attribute]: 具有属性的元素,例如 [href]
  • [^attr]: 具有属性名称前缀的[^data-]元素,例如查找具有 HTML5 数据集属性的元素
  • [attr=value]: 具有属性值的元素,例如[width=500](也可引用,如[data-name='launch sequence']
  • [attr^=value], [attr$=value], [attr*=value]: 具有以该值开头、以该值结尾或包含该值的属性的元素,例如[href*=/path/]
  • [attr~=regex]: 属性值与正则表达式匹配的元素;例如img[src~=(?i).(png|jpe?g)]
  • *: 所有元素,例如 *

选择器组合

  • el#id: 带有 ID 的元素,例如 div#logo
  • el.class: 具有类的元素,例如 div.masthead
  • el[attr]: 具有属性的元素,例如 a[href]
  • 任何组合,例如 a[href].highlight
  • ancestor child:从祖先继承下来的子元素,例如在类“body”的块下的任何位置.body p查找p元素
  • parent > child: 直接从父元素下降的子元素,例如div.content > p查找p元素;并body > *找到 body 标签的直接子代
  • siblingA + siblingB: 查找紧跟在兄弟 A 之前的兄弟 B 元素,例如 div.head + div
  • siblingA ~ siblingX: 查找兄弟 A 前面的兄弟 X 元素,例如 h1 ~ p
  • el, el, el: 对多个选择器进行分组,找到与任何选择器匹配的唯一元素;例如div.masthead, div.logo

伪选择器

  • :lt(n): 查找同级索引(即它在 DOM 树中相对于其父级的位置)小于 的元素n;例如td:lt(3)
  • :gt(n): 查找同级索引大于 的元素n;例如div p:gt(2)
  • :eq(n): 查找同级索引等于 的元素n;例如form input:eq(1)
  • :has(selector): 查找包含与选择器匹配的元素的元素;例如div:has(p)
  • :not(selector): 查找与选择器不匹配的元素;例如div:not(.logo)
  • :contains(text): 查找包含给定文本的元素。搜索不区分大小写;例如p:contains(jsoup)
  • :containsOwn(text): 查找直接包含给定文本的元素
  • :matches(regex): 查找文本与指定正则表达式匹配的元素;例如div:matches((?i)login)
  • :matchesOwn(regex): 查找自身文本与指定正则表达式匹配的元素
  • 【注意】上述索引伪选择器是基于 0 的,即第一个元素在索引 0 处,第二个元素在 1 处,以此类推

【参考文档】

jsoup.org/cookbook/in…