美文网首页
Randall | 四、Jsoup

Randall | 四、Jsoup

作者: mrzhqiang | 来源:发表于2017-10-15 21:26 被阅读0次

一、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()方法获取下一个子元素
调用next方法
  • 用prev()方法获取前一个子元素
调用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设计师!),以及第一个真正的页面。

相关文章

网友评论

      本文标题:Randall | 四、Jsoup

      本文链接:https://www.haomeiwen.com/subject/lxmcuxtx.html