使用Jsoup解析Html

时间:2022-11-01 00:20:44

在抓取网络上的资源时,我们经常会和网页打交道,很多时候我们都需要网页上的资源进行抓取,这个时候Jsoup就能帮助我们快速解析Html页面的结构,并分离出我们想要的资源。

解析一个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);

通过Jsoup.parse方法将目标字符串解析成一个文档,该文档将页面中的各种元素都组织成对应的文档节点,具体的对象模型如下:

  • 文档由多个Elements和TextNodes组成
  • 其继承结构如下:Document继承Element继承Node. TextNode继承 Node.
  • 一个Element包含一个子节点集合,并拥有一个父Element。他们还提供了一个唯一的子元素过滤列表。

使用选择器语法来查找元素

Jsoup可以让我们使用类似于CSS或jQuery的语法来查找和操作元素,这种方法查找起来十分方便快捷。

Elements links = doc.select("a[href]"); //带有href属性的a元素
Elements pngs = doc.select("img[src$=.png]");
//扩展名为.png的图片

Element masthead = doc.select("div.masthead").first();
//class等于masthead的div标签

Elements resultLinks = doc.select("h3.r > a"); //在h3元素之后的a元素

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

Selector选择器常见语法

  • tagname: 通过标签查找元素,比如:a
  • *: 这个符号将匹配所有元素
  • #id: 通过ID查找元素,比如:#logo
  • .class: 通过class名称查找元素,比如:.masthead
  • [attribute]: 利用属性查找元素,比如:[href]
  • [attr=value]: 利用属性值来查找元素,比如:[width=500]
  • [^attr]: 利用属性名前缀来查找元素,比如:可以用[^data-] 来查找带有HTML5 Dataset属性的元素
  • [attr^=value], [attr$=value], [attr*=value]: 利用匹配属性值开头、结尾或包含属性值来查找元素,比如:[href*=/path/]
  • [attr~=regex]: 利用属性值匹配正则表达式来查找元素,比如: img[src~=(?i).(png|jpe?g)]

语法组合使用

  • el#id: 元素+ID,比如: div#logo
  • el.class: 元素+class,比如: div.masthead
  • el[attr]: 元素+class,比如: a[href]
  • 任意组合,比如:a[href].highlight
  • ancestor child: 查找某个元素下子元素,比如:可以用.body p 查找在”body”元素下的所有 p元素
  • el, el, el:多个选择器组合,查找匹配任一选择器的唯一元素,例如:div.masthead, div.logo
  • siblingA + siblingB: 查找在A元素之前第一个同级元素B,比如:div.head + div
  • siblingA ~ siblingX: 查找A元素之前的同级X元素,比如:h1 ~ p

通过这些灵活的选择器,我们可以快速定位我们想要的资源,并且对其进行抽取或修改。

从一组Element里抽取资源

如果网页上有一组同类资源排列在一起,通过上面的语法我们一般会得到一个同类型的资源集合,通过遍历这个集合我们就能对各个资源逐一访问。例如:网页的《p》元素中,包含很多链接《a》,如下图所示:

使用Jsoup解析Html

则需要通过迭代器形式对每个《a》进行访问.


Elements p = doc.select("p.kw_main");
Iterator<Element> keywords = p.select("a").iterator();
String keywordString = "";
while(keywords.hasNext()){
keywordString += keywords.next().text() + ";";
}

参考

Jsoup官方网站