【Java爬虫】Jsoup

官网
中文使用手册

jsoup.jar官网下载
jsoup.jar百度网盘下载 提取码:g6ek

jsoup是一款Java的HTML解析器,主要用来对HTML解析,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

从一个URL,文件或字符串中解析HTML;
使用DOM或CSS选择器来查找、取出数据;
可操作HTML元素、属性、文本;

Jsoup的主要类


org.jsoup.Jsoup类

Jsoup类是任何Jsoup程序的入口点,并将提供从各种来源加载和解析HTML文档的方法,Jsoup类的一些重要方法如下:
在这里插入图片描述


org.jsoup.nodes.Document类:

该类表示通过Jsoup库加载HTML文档。可以使用此类执行适用于整个HTML文档的操作。Document类的重要方法参见:http://jsoup.org/apidocs/org/jsoup/nodes/Document.html,Document类的常用方法如下所示:
在这里插入图片描述

org.jsoup.nodes.Element类:

HTML元素是由标签名称,属性和子节点组成。 使用Element类可以提取数据,遍历节点和操作HTMLElement类的重要方法可以参见 :http://jsoup.org/apidocs/org/jsoup/nodes/Element.html,Element类常用方法如下所示:
在这里插入图片描述

准备工作

创建一个Jsoup工程,目录结构如下:
在这里插入图片描述
要添加jsoup的jar包,放到了百度网盘里,版本是:jsoup-1.11.3

爬取内容案例


爬取网页内容

从URL加载文档,使用Jsoup.connect()方法从URL加载

待爬取的页面信息如下图:
在这里插入图片描述


代码为:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;

/**
 * 获取 http://www.ygdy8.net/html/gndy/index.html 页面的“国内电影下载排行“
 */
public class JsoupDemo {
    
    
    public static void main(String[] args) {
    
    
        //URLLoader 是一个静态方法,可以通过类名直接调用
        JsoupDemo.URLLoader("http://www.ygdy8.net/html/gndy/index.html");
    }

    public static void URLLoader(String url){
    
    
        Document d1;

        try {
    
    
            //通过Jsoup类中的静态方法connect返回Document对象,该document对象实际为整个html页面内容。
            d1 = Jsoup.connect(url).get();
            System.out.println("网页的标题是:" + d1.title() + "\n");

            /**
             * 1. 分析网页结构,发现我们想要的国内电影下载排行榜,所对应的class样式为co_content2,
             * 2. 可以通过属性、后代选择器选中元素" div[class=‘co_content2’] ul a" ,然
             * 3. 后通过Element类中的text()方法获取文本内容
             */
            Elements es = d1.select("div[class='co_content2'] ul a");

            //遍历得到的结果并输出内容
            for (Element e : es){
    
    
                System.out.println(e.text());
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

爬取文档内容

从文件加载文档,使用Jsoup.parse()方法从文件加载HTML

待爬取的页面如下,是我本地路径下的一个html文档
在这里插入图片描述

代码为:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;

/**
 * 从本地文件加载文档,获取淘宝主营区域包括哪些方面 文件路径为: C:\Users\vsue\Desktop\taobao.html
 */
public class JsoupDocDemo {
    
    
    public static void main(String[] args) {
    
    
        JsoupDocDemo.LocLoader("C:\\Users\\vsue\\Desktop\\taobao.html");
    }

    public static void LocLoader(String address) {
    
    
        Document d2;
        try {
    
    
            //从文件加载文档,使用`Jsoup.parse()`方法从文件加载HTML
            d2 = Jsoup.parse(new File(address), "utf-8");
            System.out.println(d2.title());

            Elements es = d2.select("ul[class='service-bd'] li a");

            for (Element e : es){
    
    
                System.out.println(e.text());
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

    }
}

结果为:
在这里插入图片描述


爬取String的内容

从String加载文档,使用Jsoup.parse()方法从字符串加载HTML

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JsoupStrDemo {
    
    
    public static void main(String[] args) {
    
    
        String html = "<html>"
                + "<head>"
                + "<title>First parse</title>"
                + "</head>"
                + "<body>"
                + "<p>Parsed HTML into a doc.</p>"
                + "<a href='http://www.baidu.com'>百度一下</a>"
                + "</body>"
                + "</html>";
        JsoupStrDemo.StringLoader(html);
    }
    public static void StringLoader(String html){
    
    
        //从String加载文档,使用Jsoup.parse()方法从字符串加载HTML
        Document d3 = Jsoup.parse(html);
        String url = d3.select("a").attr("href");
        System.out.println(d3.title()+"    "+url);
    }
}

结果:
在这里插入图片描述

获取页面所有链接

一个页面中往往包含大量的url,跳转到不同的界面,接下来定义方法获取京东主页面所有url

爬取页面中所有<a> 标签,然后遍历即可

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;

/**
 * 获取HTML页面中的所有链接
 */
public class JsoupAllUrlDemo {
    
    
    public static void main(String[] args) {
    
    
        JsoupAllUrlDemo.allUrlLoader("https://www.jd.com/");
    }
    public static void allUrlLoader(String address){
    
    

        Document d4;
        try {
    
    
            d4 = Jsoup.connect(address).get();

            //links包含了页面所有的连接
            Elements links = d4.select("a[href]");
            for (Element link : links) {
    
    
                System.out.println("text : " + link.text()+"---》link : " + link.attr("href"));
            }
        } catch (IOException e) {
    
    
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

解析一个body片段

办法
使用Jsoup.parseBodyFragment(String html)方法.

String html = "<div><p>Lorem ipsum.</p>";
Document doc = Jsoup.parseBodyFragment(html);
Element body = doc.body();

说明
parseBodyFragment 方法创建一个空壳的文档,并插入解析过的HTML到body元素中。假如你使用正常的 Jsoup.parse(String html) 方法,通常你也可以得到相同的结果,但是明确将用户输入作为 body片段处理,以确保用户所提供的任何糟糕的HTML都将被解析成body元素。

Document.body() 方法能够取得文档body元素的所有子元素,与 doc.getElementsByTag("body")相同。

数据抽取

DOM方法遍历文档

将HTML解析成一个Document之后,就可以使用类似于DOM的方法进行操作。示例代码:
在这里插入图片描述

说明
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()获取元素内HTMLhtml(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)

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

方法
可以使用Element.select(String selector)Elements.select(String selector) 方法实现查找和操作元素:

在这里插入图片描述

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§表示哪些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()方法
    在这里插入图片描述

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

  • Element.id()
  • Element.tagName()
  • Element.className() and Element.hasClass(String className)
    这些访问器方法都有相应的setter方法来更改数据.


修改数据

问题

在你解析一个Document之后可能想修改其中的某些属性值,
然后再保存到磁盘或都输出到前台页面。

方法
可以使用属性设置方法 Element.attr(String key, String value), 和 Elements.attr(String key, String value).

假如你需要修改一个元素的 class 属性,可以使用 Element.addClass(String className)Element.removeClass(String className) 方法。

Elements 提供了批量操作元素属性和class的方法,比如:要为div中的每一个a元素都添加一个 rel=“nofollow” 可以使用如下方法:

doc.select("div.comments a").attr("rel", "nofollow");

说明
与Element中的其它方法一样, attr 方法也是返回当 Element (或在使用选择器是返回 Elements 集合)。这样能够很方便使用方法连用的书写方式。比如:

doc.select("div.masthead").attr("title", "jsoup").addClass("round-box");


设置一个元素的HTML内容

在这里插入图片描述
说明

  • Element.html(String html) 这个方法将先清除元素中的HTML内容,然后用传入的HTML代替。
  • Element.prepend(String first)Element.append(String last) 方法用于在分别在元素内部HTML的前面和后面添加HTML内容
  • Element.wrap(String around) 对元素包裹一个外部HTML内容。

设置元素的文本内容

方法
可以使用Element的设置方法修改一个HTML文档中的文本内容:
在这里插入图片描述

说明
文本设置方法与 HTML setter 方法一样:

  • Element.text(String text) 将清除一个元素中的内部HTML内容,然后提供的文本进行代替
  • Element.prepend(String first)Element.append(String last) 将分别在元素的内部html前后添加文本节点。

对于传入的文本如果含有像 <, > 等这样的字符,将以文本处理,而非HTML。

猜你喜欢

转载自blog.csdn.net/weixin_45468845/article/details/108563904