一、Jsoup是什么?
引用Jsoup官网的介绍:
jsoup: Java HTML Parser
jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods.
具体有什么作用?像浏览器F12那样,将网页源码分成节点和子节点,很轻松就可以提取网页上的一个个元素。这种功能十分强大,配合强大的网络工具,可以自己写爬虫去扒【小网站】。比如:在Retrofit的Sample中,就用Jsoup配合Retrofit实现了一个简单爬虫程序。
二、我有点想用了,但有没有入门文档?
而且还可以找到中文版
三、如何用Jsoup解析haowanba.com?
好玩吧主页
下面开始我们的表演:
- 使用URL生成资源链接
URL url = new URL("http://haowanba.com");
- 使用Jsoup解析这个URl
Document home = Jsoup.parse(url, (int) TimeUnit.SECONDS.toMillis(10));
System.out.println(home);
- 输出本次结果
<!--?xml version="1.0" encoding="utf-8"?-->
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>好玩吧</title>
</head>
<body>
<p>
[图片上传失败...(image-702e2e-1544607507738)]
<br>
<a href="cardh.php?action=register">注册</a>.
<a href="loginh.php?exuid=">登录</a>
.
<a href="linkh.php?action=coop">加盟</a>
<br>
[图片上传失败...(image-2682b2-1544607507738)]
<br>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy61.jsp&_do=game">[轮回]</a>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy60.jsp&_do=game">[御龙]</a>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy59.jsp&_do=game">[通灵]</a>
<br>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy50.jsp&_do=game">[战魂]</a>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy29.jsp&_do=game">[天启]</a>
<a href="http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy5.jsp&_do=game">[永恒]</a>
<br>
=================
<br>
<a href="bannerh.php?page=0">友链</a>
|
<a href="linkh.php?action=intro">简介</a>
|
<a href="linkh.php?action=touch">联系</a>
|
<a href="linkh.php?action=coop">合作</a>
<br>
荣唐科技 10-15 12:20
<br>
<a href="http://www.miitbeian.gov.cn">京ICP备17055155号</a>
| 京ICP证100435号
<br>
</p>
</body>
</html>
- 通过Html约定的元素名(title、body)获取内容
String title = home.title();
System.out.println(title);
Element body = home.body();
System.out.println(body);
- 取得元素的所有子元素/父元素——不会返回null
Elements bodyList = body.children();
Elements bodyList = body.parent();
- 取得元素的子元素
// 第一个子元素
Element first = bodyList.first();
// 按下标获取子元素(可以配合size进行ForEach)
Element index = bodyList.get(1);
// 最后一个子元素,返回与第一个有可能相同
Element first = bodyList.last();
注意:由于bodyList只有一个p元素,因此get(1)时会抛出下标越界异常
下标越界异常- 可以用next()方法获取下一个子元素
- 用prev()方法获取前一个子元素
注意,next和prev在当前实例下,返回的永远是相同的内容,因为它是在“询问子元素有没有上下文”
可以重复使用next()方法去获得下一个的下一个的下一个,这种链式调用很方便,但对于数量繁多的同级元素来讲,还是用ForEach遍历舒服些。
- 子元素的类似方法
bodyList.first().children().first().nextElementSibling()
bodyList.first().children().first().previousElementSibling()
- 解析为Markdown文档(Element是Node的扩展类)
public static final SimpleDateFormat DATE_NORMAL =
new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
public static final SimpleDateFormat DATE_HMS =
new SimpleDateFormat("HH-mm-ss_SSS", Locale.getDefault());
public static String parseNode(Node node) {
StringBuilder contentSb = new StringBuilder();
String nodeName = node.nodeName();
switch (nodeName) {
case "p":
for (Node child : node.childNodes()) {
contentSb.append(parseNode(child));
}
return contentSb.toString();
case "a":
Element a = (Element) node;
return "[" + a.text() + "]" + "(" + a.absUrl("href") + ")";
case "img":
return "![img.png]" + "(" + node.absUrl("src") + ")";
case "br":
return "\r\n \r\n";
case "#text":
// 如果是文字内容,查看源码可知匹配nodeName为#text
return node.toString();
}
return "";
}
public static void createFileByString(String title, String content) throws IOException {
Date now = new Date();
File file = new File(".\\wml2md\\" + DATE_NORMAL.format(now));
if (!file.exists()) {
file.mkdirs();
}
file = new File(file, title + DATE_HMS.format(now) + ".md");
if (!file.exists()) {
file.createNewFile();
}
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write(content);
writer.flush();
writer.close();
}
--- 文档内容
![img.png](https://img.haomeiwen.com/i7426376/fdf73d8c9cd674b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
[注册](http://haowanba.com/cardh.php?action=register).[登录](http://haowanba.com/loginh.php?exuid=).[加盟](http://haowanba.com/linkh.php?action=coop)
![img.png](https://img.haomeiwen.com/i7426376/91897469a522e76b.gif?imageMogr2/auto-orient/strip)
[[轮回]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy61.jsp&_do=game)[[御龙]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy60.jsp&_do=game)[[通灵]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy59.jsp&_do=game)
[[战魂]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy50.jsp&_do=game)[[天启]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy29.jsp&_do=game)[[永恒]](http://haowanba.com/cardh.php?action=register&url=http://dy.haowanba.com/dy/dy5.jsp&_do=game)
=================
[友链](http://haowanba.com/bannerh.php?page=0)|[简介](http://haowanba.com/linkh.php?action=intro)|[联系](http://haowanba.com/linkh.php?action=touch)|[合作](http://haowanba.com/linkh.php?action=coop)
荣唐科技 10-15 12:44
[京ICP备17055155号](http://www.miitbeian.gov.cn) | 京ICP证100435号
--- 直接展示
img.png img.png
=================
荣唐科技 10-15 12:44
京ICP备17055155号 | 京ICP证100435号
四、总结
jsoup作为网页解析神器,比simple-xml实在强大太多,尽管simple-xml可以快捷定位文档、元素这些节点,但对于元素之间存在的多个文本,居然没有一个合适的方法去获取。经过几天的探索之后,只能暂时抛弃simple-xml,转向jsoup的怀抱。
接下来的兰达尔,将拥有个性化的应用图标(你其实不需要UI设计师!),以及第一个真正的页面。
网友评论