jsoup 是一款 Java 的HTML
解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操
作数据。请参考:
http://jsoup.org/
jsoup的主要功能如下:
从一个URL,文件或字符串中解析HTML;
使用DOM或CSS选择器来查找、取出数据;
可操作HTML元素、属性、文本;
jsoup是基于MIT协议发布的,可放心使用于商业项目。
下载和安装:
maven安装方法:
把下面放入pom.xml下
<dependency>
<!-- jsoup HTML parser
library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.5.2</version>
</dependency>
用jsoup解析html的方法如下:
解析url html方法
Document
doc
=
Jsoup
.
connect
(
"http://example.com"
)
.
data
(
"query"
,
"Java"
)
.
userAgent
(
"Mozilla"
)
.
cookie
(
"auth"
,
"token"
)
.
timeout
(
3000
)
.
post
();
从文件中解析的方法:
File
input
=
new
File
(
"/tmp/input.html"
);
Document
doc
=
Jsoup
.
parse
(
input
,
"UTF-8"
,
"http://example.com/"
);
类试js jsoup提供下面方法:
同时还提供下面的方法提供获取兄弟节点:
siblingElements()
, firstElementSibling()
, lastElementSibling()
;nextElementSibling()
, previousElementSibling()
用下面方法获得元素的数据:
操作html提供了下面方法:
通过类似jquery的方法操作html
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
操作tag
-
ns|tag
ns或tag
-
#id
用id获得元素
-
.class
用class获得元素
-
[attribute]
属性获得元素
-
[^attr]
: 以attr开头的属性
-
[attr=value] 属性值为
value
-
[attr^=value]
, [attr$=value]
, [attr*=value]
-
[attr~=regex]
正则
-
*
:所以的标签
选择组合
-
el#id
el和id定位
-
el.class
e1和class定位
-
el[attr]
e1和属性定位
-
ancestor child
ancestor下面的
child
等等
抓取网站标题和内容及里面图片的事例:
-
public
void
parse(String urlStr) {
-
-
-
Document doc = null
;
-
try
{
-
doc = Jsoup
-
.connect(urlStr)
-
.userAgent(
-
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)"
)
-
.timeout(5000
)
-
.get();
-
} catch
(MalformedURLException e) {
-
log.error( e);
-
return
;
-
} catch
(IOException e) {
-
if
(e
instanceof
SocketTimeoutException) {
-
log.error( e);
-
return
;
-
}
-
if
(e
instanceof
UnknownHostException){
-
log.error(e);
-
return
;
-
}
-
log.error( e);
-
return
;
-
}
-
system.out.println(doc.title());
-
Element head = doc.head();
-
Elements metas = head.select("meta"
);
-
for
(Element meta : metas) {
-
String content = meta.attr("content"
);
-
if
(
"content-type"
.equalsIgnoreCase(meta.attr(
"http-equiv"
))
-
&& !StringUtils.startsWith(content, "text/html"
)) {
-
log.debug( urlStr);
-
return
;
-
}
-
if
(
"description"
.equalsIgnoreCase(meta.attr(
"name"
))) {
-
system.out.println(meta.attr("content"
));
-
}
-
}
-
Element body = doc.body();
-
for
(Element img : body.getElementsByTag(
"img"
)) {
-
String imageUrl = img.attr("abs:src"
);
-
for
(String suffix : IMAGE_TYPE_ARRAY) {
-
if
(imageUrl.indexOf(
"?"
)>
0
){
-
imageUrl=imageUrl.substring(0
,imageUrl.indexOf(
"?"
));
-
}
-
if
(StringUtils.endsWithIgnoreCase(imageUrl, suffix)) {
-
imgSrcs.add(imageUrl);
-
break
;
-
}
-
}
-
}
-
}
public void parse(String urlStr) {
// 返回结果初始化。
Document doc = null;
try {
doc = Jsoup
.connect(urlStr)
.userAgent(
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)") // 设置User-Agent
.timeout(5000) // 设置连接超时时间
.get();
} catch (MalformedURLException e) {
log.error( e);
return ;
} catch (IOException e) {
if (e instanceof SocketTimeoutException) {
log.error( e);
return ;
}
if(e instanceof UnknownHostException){
log.error(e);
return ;
}
log.error( e);
return ;
}
system.out.println(doc.title());
Element head = doc.head();
Elements metas = head.select("meta");
for (Element meta : metas) {
String content = meta.attr("content");
if ("content-type".equalsIgnoreCase(meta.attr("http-equiv"))
&& !StringUtils.startsWith(content, "text/html")) {
log.debug( urlStr);
return ;
}
if ("description".equalsIgnoreCase(meta.attr("name"))) {
system.out.println(meta.attr("content"));
}
}
Element body = doc.body();
for (Element img : body.getElementsByTag("img")) {
String imageUrl = img.attr("abs:src");//获得绝对路径
for (String suffix : IMAGE_TYPE_ARRAY) {
if(imageUrl.indexOf("?")>0){
imageUrl=imageUrl.substring(0,imageUrl.indexOf("?"));
}
if (StringUtils.endsWithIgnoreCase(imageUrl, suffix)) {
imgSrcs.add(imageUrl);
break;
}
}
}
}
这里重点要
提的是怎么获得图片或链接的决定地址:
如上获得绝对地址的方法String imageUrl = img.attr("abs:src");//获得绝对路径
,前面添加abs:jsoup就会获得决定地址;
想知道原因,咱们查看下源
码,如下:
-
-
-
public
String attr(String attributeKey) {
-
Validate.notNull(attributeKey);
-
-
if
(hasAttr(attributeKey))
-
return
attributes.get(attributeKey);
-
else
if
(attributeKey.toLowerCase().startsWith(
"abs:"
))
-
return
absUrl(attributeKey.substring(
"abs:"
.length()));
-
else
return
""
;
-
}
//该方面是先从map中找看是否有该属性key,如果有直接返回,如果没有检查是否
//以abs:开头
public String attr(String attributeKey) {
Validate.notNull(attributeKey);
if (hasAttr(attributeKey))
return attributes.get(attributeKey);
else if (attributeKey.toLowerCase().startsWith("abs:"))
return absUrl(attributeKey.substring("abs:".length()));
else return "";
}
接着查看absUrl方法:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public
String absUrl(String attributeKey) {
-
Validate.notEmpty(attributeKey);
-
-
String relUrl = attr(attributeKey);
-
if
(!hasAttr(attributeKey)) {
-
return
""
;
-
} else
{
-
URL base;
-
try
{
-
try
{
-
base = new
URL(baseUri);
-
} catch
(MalformedURLException e) {
-
-
URL abs = new
URL(relUrl);
-
return
abs.toExternalForm();
-
}
-
-
if
(relUrl.startsWith(
"?"
))
-
relUrl = base.getPath() + relUrl;
-
URL abs = new
URL(base, relUrl);
-
return
abs.toExternalForm();
-
} catch
(MalformedURLException e) {
-
return
""
;
-
}
-
}
-
}
/**
* Get an absolute URL from a URL attribute that may be relative (i.e. an <code><a href></code> or
* <code><img src></code>).
* <p/>
* E.g.: <code>String absUrl = linkEl.absUrl("href");</code>
* <p/>
* If the attribute value is already absolute (i.e. it starts with a protocol, like
* <code>http://</code> or <code>https://</code> etc), and it successfully parses as a URL, the attribute is
* returned directly. Otherwise, it is treated as a URL relative to the element's {@link #baseUri}, and made
* absolute using that.
* <p/>
* As an alternate, you can use the {@link #attr} method with the <code>abs:</code> prefix, e.g.:
* <code>String absUrl = linkEl.attr("abs:href");</code>
*
* @param attributeKey The attribute key
* @return An absolute URL if one could be made, or an empty string (not null) if the attribute was missing or
* could not be made successfully into a URL.
* @see #attr
* @see java.net.URL#URL(java.net.URL, String)
*/
//看到这里大家应该明白绝对地址是怎么取的了
public String absUrl(String attributeKey) {
Validate.notEmpty(attributeKey);
String relUrl = attr(attributeKey);
if (!hasAttr(attributeKey)) {
return ""; // nothing to make absolute with
} else {
URL base;
try {
try {
base = new URL(baseUri);
} catch (MalformedURLException e) {
// the base is unsuitable, but the attribute may be abs on its own, so try that
URL abs = new URL(relUrl);
return abs.toExternalForm();
}
// workaround: java resolves '//path/file + ?foo' to '//path/?foo', not '//path/file?foo' as desired
if (relUrl.startsWith("?"))
relUrl = base.getPath() + relUrl;
URL abs = new URL(base, relUrl);
return abs.toExternalForm();
} catch (MalformedURLException e) {
return "";
}
}
}
分享到:
相关推荐
100多行实现的csdn博客访问量自动刷新程序,原理很简单通过jsoup爬虫框架,获取对于的链接,spring的RestTemplete发送http请求 引入的依赖 <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --> ...
使用 HttpUrlConnection 类发送 HTTP 请求,接着使用 Jsoup 对响应的 HTML 页面进行解析,获取我们想要的数据。最后,我们将获取的数据存储到数据库中,这里使用了 Mybatis-Plus 提供的 insert 方法。
2. HTTP请求:爬虫向目标URL发送HTTP请求,获取网页内容。这可能涉及到处理请求头、设置代理、处理Cookie等操作。 3. 内容获取:爬虫接收到HTTP响应后,获取响应的内容,通常是HTML、XML或JSON等格式的文档。 4. ...
网页抓取:爬虫首先通过网络请求获取网页内容。它们可以模拟浏览器行为发送 HTTP 请求,或者直接与服务器通信获取网页数据。 解析网页:获取到网页内容后,爬虫需要解析 HTML 或其他标记语言,提取出有用的信息,如...
1. **发送请求**:使用Java的网络库向目标网页发送HTTP请求。 2. **解析网页**:获取响应的HTML内容,并使用解析库(如Jsoup)提取所需的数据。 3. **提取数据**:编写逻辑代码,从解析后的HTML中提取目标信息。 ...
这是一个Java Swing项目,通过HttpClient和Jsoup抓取网站数据 数据分析 显示开奖信息包括:期号、开奖时间、开奖结果、已投注数、金蛋总数、中奖人数等 报表统计 单双/大小饼状图,0~27出现次数柱状图 系统设置 设置...
网页抓取:使用Java的网络编程库(如HttpURLConnection、Apache HttpClient等)来发送HTTP请求,获取网页的HTML内容。 网页解析:利用Java的HTML解析库(如Jsoup、HtmlCleaner等)来解析网页的HTML结构,提取出所需...
Apache HttpClient:一个用于发送HTTP请求的Java库,可以用于获取网页内容。 JSoup:一个基于Java的JavaScript解析器,可以用于解析HTML文档。 WebMagic:一个开源的爬虫框架,提供了一些高级特性,如自动化抽取和...
这个简单的网络抓取工具应用通过swagger-ui或使用API交互客户端工具(如Postman)(位于通过提供的Api接受用户的 。 用户必须在上述终点处发送POST请求,请求正文为{“ url”:“ ”},并希望收到2XX成功消息。 ...
cache EhCacheUtils - 基于ehcache的工具类 LruCacheUtils - 基于LinkedHashMap实现LRU...HttpUtils - 发送HTTP请求 IpUtils - 获取IP SFtpUtils - 操作SFTP的工具类 prop PropertiesUtils - 操作properties配置文件
原理:通过HttpClient对象向中央气象台官网的城市天气查询服务页发送查询请求,获取响应后使用jsoup解析返回的html文档,将天气信息提取出来。使用时需要将附带的jar包添加到项目的classpath中。
当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。 QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...
当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。 QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...
3、连接复用,因此在多线程获取连接时无需阻塞; 4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换...