您的位置:首页 > 编程语言 > Java开发

非常好用的一个Html解析的java类库 Jsoup

2015-11-11 11:38 676 查看


http://www.open-open.com/jsoup/parsing-a-document.htm


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


(更详细内容可查看 解析一个HTML字符串.)

其解析器能够尽最大可能从你提供的HTML文档来创见一个干净的解析结果,无论HTML的格式是否完整。比如它可以处理:
没有关闭的标签 (比如: 
<p>Lorem <p>Ipsum
 parses
to 
<p>Lorem</p> <p>Ipsum</p>
)
隐式标签 (比如. 它可以自动将 
<td>Table
data</td>
包装成
<table><tr><td>?
)
创建可靠的文档结构(html标签包含head 和 body,在head只出现恰当的元素)


一个文档的对象模型

文档由多个Elements和TextNodes组成 (以及其它辅助nodes:详细可查看:nodes package
tree).
其继承结构如下:
Document
继承
Element
继承
Node
TextNode
继承 
Node
.
一个Element包含一个子节点集合,并拥有一个父Element。他们还提供了一个唯一的子元素过滤列表。


参见

数据抽取:DOM遍历
数据抽取:Selector syntax


从一个URL加载一个Document


存在问题

你需要从一个网站获取和解析一个HTML文档,并查找其中的相关数据。你可以使用下面解决方法:


解决方法

使用 
Jsoup.connect(String
url)
方法:
Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();


说明

connect(String
url)
 方法创建一个新的 
Connection
,
和 
get()
 取得和解析一个HTML文件。如果从该URL获取HTML时发生错误,便会抛出
IOException,应适当处理。

Connection
 接口还提供一个方法链来解决特殊请求,具体如下:
Document doc = Jsoup.connect("http://example.com")
.data("query", "Java")
.userAgent("Mozilla")
.cookie("auth", "token")
.timeout(3000)
.post();


这个方法只支持Web URLs (
http
https
 协议);
假如你需要从一个文件加载,可以使用
parse(File
in, String charsetName)
 代替。


从一个文件加载一个文档


问题

在本机硬盘上有一个HTML文件,需要对它进行解析从中抽取数据或进行修改。


办法

可以使用静态 
Jsoup.parse(File
in, String charsetName, String baseUri)
 方法:
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");


说明

parse(File
in, String charsetName, String baseUri)
 这个方法用来加载和解析一个HTML文件。如在加载文件的时候发生错误,将抛出IOException,应作适当处理。

baseUri
 参数用于解决文件中URLs是相对路径的问题。如果不需要可以传入一个空的字符串。

另外还有一个方法
parse(File
in, String charsetName)
 ,它使用文件的路径做为 
baseUri
。 这个方法适用于如果被解析文件位于网站的本地文件系统,且相关链接也指向该文件系统。


使用DOM方法来遍历一个文档


问题

你有一个HTML文档要从中提取数据,并了解这个HTML文档的结构。


方法

将HTML解析成一个
Document
之后,就可以使用类似于DOM的方法进行操作。示例代码:
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
String linkHref = link.attr("href");
String linkText = link.text();
}


说明

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


查找元素

getElementById(String
id)

getElementsByTag(String
tag)

getElementsByClass(String
className)

getElementsByAttribute(String
key)
 (and related methods)
Element siblings: 
siblingElements()
firstElementSibling()
lastElementSibling()
;
nextElementSibling()
previousElementSibling()

Graph: 
parent()
children()
child(int
index)


元素数据

attr(String
key)
获取属性
attr(String
key, String value)
设置属性
attributes()
获取所有属性
id()
className()
 and 
classNames()

text()
获取文本内容
text(String
value)
 设置文本内容
html()
获取元素内HTML
html(String
value)
设置元素内的HTML内容
outerHtml()
获取元素外HTML内容
data()
获取数据内容(例如:script和style标签)
tag()
 and 
tagName()


操作HTML和文本

append(String
html)
prepend(String
html)

appendText(String
text)
prependText(String
text)

appendElement(String
tagName)
prependElement(String
tagName)

html(String
value)



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


问题

你想使用类似于CSS或jQuery的语法来查找和操作元素。


方法

可以使用
Element.select(String
selector)
 和 
Elements.select(String
selector)
 方法实现:
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
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元素


说明

jsoup elements对象支持类似于CSS (或jquery)的选择器语法,来实现非常强大和灵活的查找功能。.

这个
select
 方法在
Document
Element
,或
Elements
对象中都可以使用。且是上下文相关的,因此可实现指定元素的过滤,或者链式选择访问。

Select方法将返回一个
Elements
集合,并提供一组方法来抽取和处理结果。


Selector选择器概述

tagname
: 通过标签查找元素,比如:
a

ns|tag
: 通过标签在命名空间查找元素,比如:可以用 
fb|name
 语法来查找 
<fb:name>
 元素
#id
: 通过ID查找元素,比如:
#logo

.class
: 通过class名称查找元素,比如:
.masthead

[attribute]
: 利用属性查找元素,比如:
[href]

[^attr]
: 利用属性名前缀来查找元素,比如:可以用
[^data-]
 来查找带有HTML5
Dataset属性的元素
[attr=value]
: 利用属性值来查找元素,比如:
[width=500]

[attr^=value]
[attr$=value]
[attr*=value]
:
利用匹配属性值开头、结尾或包含属性值来查找元素,比如:
[href*=/path/]

[attr~=regex]
: 利用属性值匹配正则表达式来查找元素,比如: 
img[src~=(?i)\.(png|jpe?g)]

*
: 这个符号将匹配所有元素


Selector选择器组合使用

el#id
: 元素+ID,比如: 
div#logo

el.class
: 元素+class,比如: 
div.masthead

el[attr]
: 元素+class,比如: 
a[href]

任意组合,比如:
a[href].highlight

ancestor child
:
查找某个元素下子元素,比如:可以用
.body p
 查找在"body"元素下的所有
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


伪选择器selectors

:lt(n)
: 查找哪些元素的同级索引值(它的位置在DOM树中是相对于它的父节点)小于n,比如:
td:lt(3)
 表示小于三列的元素
:gt(n)
:查找哪些元素的同级索引值大于
n
,比如
: 
div
p:gt(2)
表示哪些div中有包含2个以上的p元素
:eq(n)
: 查找哪些元素的同级索引值与
n
相等,比如:
form
input:eq(1)
表示包含一个input标签的Form元素
:has(seletor)
: 查找匹配选择器包含元素的元素,比如:
div:has(p)
表示哪些div包含了p元素
:not(selector)
:
查找与选择器不匹配的元素,比如: 
div:not(.logo)
 表示不包含 class=logo 元素的所有 div 列表
:contains(text)
:
查找包含给定文本的元素,搜索不区分大不写,比如: 
p:contains(jsoup)

:containsOwn(text)
:
查找直接包含给定文本的元素
:matches(regex)
:
查找哪些元素的文本匹配指定的正则表达式,比如:
div:matches((?i)login)

:matchesOwn(regex)
:
查找自身包含文本匹配指定正则表达式的元素
注意:上述伪选择器索引是从0开始的,也就是说第一个元素索引值为0,第二个元素index为1等

可以查看
Selector
 API参考来了解更详细的内容


从元素抽取属性,文本和HTML


问题

在解析获得一个Document实例对象,并查找到一些元素之后,你希望取得在这些元素中的数据。


方法

要取得一个属性的值,可以使用
Node.attr(String
key)
 方法
对于一个元素中的文本,可以使用
Element.text()
方法
对于要取得元素或属性中的HTML内容,可以使用
Element.html()
,
或 
Node.outerHtml()
方法

示例:
String html = "<p>An <a href='http://example.com/'><b>example</b></a> link.</p>";
Document doc = Jsoup.parse(html);//解析HTML字符串返回一个Document实现
Element link = doc.select("a").first();//查找第一个a元素

String text = doc.body().text(); // "An example link"//取得字符串中的文本
String linkHref = link.attr("href"); // "http://example.com/"//取得链接地址
String linkText = link.text(); // "example""//取得链接地址中的文本

String linkOuterH = link.outerHtml();
// "<a href="http://example.com"><b>example</b></a>"
String linkInnerH = link.html(); // "<b>example</b>"//取得链接内的html内容


说明

上述方法是元素数据访问的核心办法。此外还其它一些方法可以使用:
Element.id()

Element.tagName()

Element.className()
 and 
Element.hasClass(String
className)


这些访问器方法都有相应的setter方法来更改数据.


参见

Element
Elements
集合类的参考文档
URLs处理
使用CSS选择器语法来查找元素


示例程序: 获取所有链接

这个示例程序将展示如何从一个URL获得一个页面。然后提取页面中的所有链接、图片和其它辅助内容。并检查URLs和文本信息。

运行下面程序需要指定一个URLs作为参数
package org.jsoup.examples;

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

import java.io.IOException;

/**
* Example program to list links from a URL.
*/
public class ListLinks {
public static void main(String[] args) throws IOException {
Validate.isTrue(args.length == 1, "usage: supply url to fetch");
String url = args[0];
print("Fetching %s...", url);

Document doc = Jsoup.connect(url).get();
Elements links = doc.select("a[href]");
Elements media = doc.select("[src]");
Elements imports = doc.select("link[href]");

print("\nMedia: (%d)", media.size());
for (Element src : media) {
if (src.tagName().equals("img"))
print(" * %s: <%s> %sx%s (%s)",
src.tagName(), src.attr("abs:src"), src.attr("width"), src.attr("height"),
trim(src.attr("alt"), 20));
else
print(" * %s: <%s>", src.tagName(), src.attr("abs:src"));
}

print("\nImports: (%d)", imports.size());
for (Element link : imports) {
print(" * %s <%s> (%s)", link.tagName(),link.attr("abs:href"), link.attr("rel"));
}

print("\nLinks: (%d)", links.size());
for (Element link : links) {
print(" * a: <%s>  (%s)", link.attr("abs:href"), trim(link.text(), 35));
}
}

private static void print(String msg, Object... args) {
System.out.println(String.format(msg, args));
}

private static String trim(String s, int width) {
if (s.length() > width)
return s.substring(0, width-1) + ".";
else
return s;
}
}
org/jsoup/examples/ListLinks.java


示例输入结果

Fetching http://news.ycombinator.com/... 
Media: (38)
* img: <http://ycombinator.com/images/y18.gif> 18x18 ()
* img: <http://ycombinator.com/images/s.gif> 10x1 ()
* img: <http://ycombinator.com/images/grayarrow.gif> x ()
* img: <http://ycombinator.com/images/s.gif> 0x10 ()
* script: <http://www.co2stats.com/propres.php?s=1138>
* img: <http://ycombinator.com/images/s.gif> 15x1 ()
* img: <http://ycombinator.com/images/hnsearch.png> x ()
* img: <http://ycombinator.com/images/s.gif> 25x1 ()
* img: <http://mixpanel.com/site_media/images/mixpanel_partner_logo_borderless.gif> x (Analytics by Mixpan.)

Imports: (2)
* link <http://ycombinator.com/news.css> (stylesheet)
* link <http://ycombinator.com/favicon.ico> (shortcut icon)

Links: (141)
* a: <http://ycombinator.com>  ()
* a: <http://news.ycombinator.com/news>  (Hacker News)
* a: <http://news.ycombinator.com/newest>  (new)
* a: <http://news.ycombinator.com/newcomments>  (comments)
* a: <http://news.ycombinator.com/leaders>  (leaders)
* a: <http://news.ycombinator.com/jobs>  (jobs)
* a: <http://news.ycombinator.com/submit>  (submit)
* a: <http://news.ycombinator.com/x?fnid=JKhQjfU7gW>  (login)
* a: <http://news.ycombinator.com/vote?for=1094578&dir=up&whence=%6e%65%77%73>  ()
* a: <http://www.readwriteweb.com/archives/facebook_gets_faster_debuts_homegrown_php_compiler.php?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+readwriteweb+%28ReadWriteWeb%29&utm_content=Twitter>  (Facebook speeds up PHP)
* a: <http://news.ycombinator.com/user?id=mcxx>  (mcxx)
* a: <http://news.ycombinator.com/item?id=1094578>  (9 comments)
* a: <http://news.ycombinator.com/vote?for=1094649&dir=up&whence=%6e%65%77%73>  ()
* a: <http://groups.google.com/group/django-developers/msg/a65fbbc8effcd914>  ("Tough. Django produces XHTML.")
* a: <http://news.ycombinator.com/user?id=andybak>  (andybak)
* a: <http://news.ycombinator.com/item?id=1094649>  (3 comments)
* a: <http://news.ycombinator.com/vote?for=1093927&dir=up&whence=%6e%65%77%73>  ()
* a: <http://news.ycombinator.com/x?fnid=p2sdPLE7Ce>  (More)
* a: <http://news.ycombinator.com/lists>  (Lists)
* a: <http://news.ycombinator.com/rss>  (RSS)
* a: <http://ycombinator.com/bookmarklet.html>  (Bookmarklet)
* a: <http://ycombinator.com/newsguidelines.html>  (Guidelines)
* a: <http://ycombinator.com/newsfaq.html>  (FAQ)
* a: <http://ycombinator.com/newsnews.html>  (News News)
* a: <http://news.ycombinator.com/item?id=363>  (Feature Requests)
* a: <http://ycombinator.com>  (Y Combinator)
* a: <http://ycombinator.com/w2010.html>  (Apply)
* a: <http://ycombinator.com/lib.html>  (Library)
* a: <http://www.webmynd.com/html/hackernews.html>  ()
* a: <http://mixpanel.com/?from=yc>  ()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: