zoukankan      html  css  js  c++  java
  • Jsoup入门学习一

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

    2、Jsoup 的主要功能,如下所示:

      1)、从一个URL,文件或字符串中解析HTML;
      2)、使用DOM或CSS选择器来查找、取出数据;
      3)、可操作HTML元素、属性、文本;
      4)、Jsoup 是基于MIT协议发布的,可放心使用于商业项目。

    3、httpClient 结合Jsoup 获取到网页内容进行解析,首先需要引入httpClient和Jsoup的依赖,如下所示:

     1 <project xmlns="http://maven.apache.org/POM/4.0.0"
     2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
     4       http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5     <modelVersion>4.0.0</modelVersion>
     6 
     7     <groupId>com.bie</groupId>
     8     <artifactId>jsoup</artifactId>
     9     <version>0.0.1-SNAPSHOT</version>
    10     <packaging>jar</packaging>
    11 
    12     <name>jsoup</name>
    13     <url>http://maven.apache.org</url>
    14 
    15     <properties>
    16         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    17     </properties>
    18 
    19     <dependencies>
    20         <!-- 添加httpclient支持 -->
    21         <dependency>
    22             <groupId>org.apache.httpcomponents</groupId>
    23             <artifactId>httpclient</artifactId>
    24             <version>4.5.2</version>
    25         </dependency>
    26         <!-- jsoup版本依赖 -->
    27         <dependency>
    28             <groupId>org.jsoup</groupId>
    29             <artifactId>jsoup</artifactId>
    30             <version>1.8.3</version>
    31         </dependency>
    32     </dependencies>
    33 </project>

    虽然使用Jsoup可以替代HttpClient直接发起请求解析数据,但是往往不会这样用,因为实际的开发过程中,需要使用到多线程,连接池,代理等等技术,而jsoup对这些技术的支持并不是很好,所以jsoup一般仅仅作为Html解析工具使用。

     1 package com.bie.spider.jsoup;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 import java.net.MalformedURLException;
     6 import java.net.URL;
     7 
     8 import org.apache.commons.io.FileUtils;
     9 import org.jsoup.Jsoup;
    10 import org.jsoup.nodes.Document;
    11 import org.jsoup.nodes.Element;
    12 
    13 /**
    14  * 
    15  * @author
    16  *
    17  */
    18 public class JsoupDocument {
    19 
    20     /**
    21      * 虽然使用Jsoup可以替代HttpClient直接发起请求解析数据,但是往往不会这样用,
    22      * 因为实际的开发过程中,需要使用到多线程,连接池,代理等等技术,
    23      * 而jsoup对这些技术的支持并不是很好, 所以jsoup一般仅仅作为Html解析工具使用
    24      * 
    25      * @throws MalformedURLException
    26      * @throws IOException
    27      */
    28     public static void inputUrl() throws MalformedURLException, IOException {
    29         // Jsoup可以直接输入url,它会发起请求并获取数据,封装为Document对象
    30         // 使用jsoup解析url
    31         Document doc = Jsoup.parse(new URL("https://www.autohome.com.cn/bestauto/"), 10000);
    32 
    33         // 把获取的内容输出为文件
    34         FileUtils.writeStringToFile(new File("D:/test.html"), doc.toString(), "UTF-8");
    35 
    36         // 获取title
    37         Element element = doc.getElementsByTag("title").first();
    38 
    39         // 打印title内容
    40         System.out.println(element.text());
    41     }
    42 
    43     /**
    44      * 输入字符串,Jsoup可以直接输入字符串,并封装为Document对象
    45      * 
    46      * @throws MalformedURLException
    47      * @throws IOException
    48      */
    49     public static void inputCharacter() throws MalformedURLException, IOException {
    50         // 读取文件,获取字符串
    51         String html = FileUtils.readFileToString(new File("D:/test.html"), "UTF-8");
    52 
    53         // 解析字符串
    54         Document doc = Jsoup.parse(html);
    55 
    56         // 获取title标签
    57         Element element = doc.getElementsByTag("title").first();
    58 
    59         // 打印title内容
    60         System.out.println(element.text());
    61     }
    62 
    63     /**
    64      * 输入文件,Jsoup可以直接输入文件,并封装为Document对象
    65      * 
    66      * @throws MalformedURLException
    67      * @throws IOException
    68      */
    69     public static void inputFile() throws MalformedURLException, IOException {
    70         // 使用jsoup解析文件
    71         Document doc = Jsoup.parse(new File("D:/test.html"), "UTF-8");
    72 
    73         // 获取title标签
    74         Element element = doc.getElementsByTag("title").first();
    75 
    76         // 打印title内容
    77         System.out.println(element.text());
    78     }
    79 
    80     public static void main(String[] args) throws MalformedURLException, IOException {
    81         // 输入url
    82         inputUrl();
    83         // 输入字符串
    84         inputCharacter();
    85         // 输入文件
    86         inputFile();
    87     }
    88 
    89 }

    httpClient 结合Jsoup 获取到网页内容进行解析,具体代码,如下所示:

     1 package com.bie.jsoup;
     2 
     3 import java.io.IOException;
     4 
     5 import org.apache.http.Header;
     6 import org.apache.http.HttpEntity;
     7 import org.apache.http.ParseException;
     8 import org.apache.http.StatusLine;
     9 import org.apache.http.client.ClientProtocolException;
    10 import org.apache.http.client.methods.CloseableHttpResponse;
    11 import org.apache.http.client.methods.HttpGet;
    12 import org.apache.http.impl.client.CloseableHttpClient;
    13 import org.apache.http.impl.client.HttpClients;
    14 import org.apache.http.util.EntityUtils;
    15 import org.jsoup.Jsoup;
    16 import org.jsoup.nodes.Document;
    17 import org.jsoup.nodes.Element;
    18 import org.jsoup.select.Elements;
    19 
    20 public class HttpClientToJsoup {
    21 
    22     // 设置请求头消息 User-Agent 模拟浏览器
    23     private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0";
    24 
    25     /**
    26      * HttpGet请求操作
    27      */
    28     public static void httpGetRequest() {
    29         // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。
    30         CloseableHttpClient httpClient = HttpClients.createDefault();
    31         // 第二步,创建HttpGet或者HttpPost实例。
    32         String uri = "https://www.cnblogs.com/biehongli";
    33         HttpGet httpGet = new HttpGet(uri);
    34         // 设置请求头消息 User-Agent 模拟浏览器
    35         httpGet.setHeader("User-Agent", UserAgent);
    36 
    37         // 定义一个可响应的实例对象。
    38         CloseableHttpResponse response = null;
    39         try {
    40             // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。
    41             response = httpClient.execute(httpGet);
    42             // 获取到响应的状态
    43             StatusLine statusLine = response.getStatusLine();
    44             System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode());
    45         } catch (ClientProtocolException e) {
    46             // http协议异常
    47             e.printStackTrace();
    48         } catch (IOException e) {
    49             // io异常
    50             e.printStackTrace();
    51         }
    52         // 第四步,获取到返回的实体对象
    53         HttpEntity entity = response.getEntity();
    54         // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西
    55         Header contentType = entity.getContentType();
    56         // 打印响应信息
    57         System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue());
    58 
    59         // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码
    60         String result = null;
    61         try {
    62             result = EntityUtils.toString(entity, "UTF-8");
    63         } catch (ParseException e) {
    64             e.printStackTrace();
    65         } catch (IOException e) {
    66             e.printStackTrace();
    67         }
    68         // 打印请求返回的结果
    69         // System.out.println(result.toString());
    70 
    71         // 讲获取到网页转换成为jsoup进行处理,返回结果为Document文档
    72         Document document = Jsoup.parse(result);
    73         Elements elements = document.getElementsByTag("title");
    74         Element element = elements.get(0);
    75         System.out.println("获取到的标题內容: " + element.text().toString());
    76 
    77         // 获取到自己的博客题目名称内容
    78         Elements elementsByClass = document.getElementsByClass("postTitle2");
    79         for (Element e : elementsByClass) {
    80             System.out.println("获取到的标题内容是: " + e.text());
    81         }
    82 
    83         // 第五步,关闭流,释放资源
    84         try {
    85             response.close();
    86             httpClient.close();
    87         } catch (IOException e) {
    88             e.printStackTrace();
    89         }
    90     }
    91 
    92     public static void main(String[] args) {
    93         HttpClientToJsoup.httpGetRequest();
    94     }
    95 
    96 }

    4、Jsoup的主要作用是,用HttpClient获取到网页后,具体的网页提取需要的信息的时候 ,就用到Jsoup,Jsoup可以使用强大的类似Jquery,css选择器,来获取需要的数据;

    Jsoup官方地址:https://jsoup.org/
    Jsoup最新下载:https://jsoup.org/download
    Jsoup学习文档:https://jsoup.org/cookbook/introduction/parsing-a-document

    5、Jsoup查找DOM元素的主要方法,如下所示:

      1)、getElementById(String id) 根据 id 来查询 DOM。
      2)、getElementsByTag(String tagName) 根据 tag 名称来查询 DOM。
      3)、getElementsByClass(String className) 根据样式名称来查询 DOM。
      4)、getElementsByAttribute(String key) 根据属性名,标签的属性元素来查询 DOM。
      5)、getElementsByAttributeValue(String key,String value) 根据属性名和属性值来查询 DOM。

    如果满足不了自己的需求,可以使用Jsoup 的选择器语法查找 DOM 元素,如下所示:

      1 package com.bie.jsoup;
      2 
      3 import java.io.IOException;
      4 
      5 import org.apache.http.Header;
      6 import org.apache.http.HttpEntity;
      7 import org.apache.http.ParseException;
      8 import org.apache.http.StatusLine;
      9 import org.apache.http.client.ClientProtocolException;
     10 import org.apache.http.client.methods.CloseableHttpResponse;
     11 import org.apache.http.client.methods.HttpGet;
     12 import org.apache.http.impl.client.CloseableHttpClient;
     13 import org.apache.http.impl.client.HttpClients;
     14 import org.apache.http.util.EntityUtils;
     15 import org.jsoup.Jsoup;
     16 import org.jsoup.nodes.Document;
     17 import org.jsoup.nodes.Element;
     18 import org.jsoup.select.Elements;
     19 
     20 public class HttpClientToJsoup {
     21 
     22     // 设置请求头消息 User-Agent 模拟浏览器
     23     private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0";
     24 
     25     /**
     26      * HttpGet请求操作
     27      */
     28     public static void httpGetRequest() {
     29         // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。
     30         CloseableHttpClient httpClient = HttpClients.createDefault();
     31         // 第二步,创建HttpGet或者HttpPost实例。
     32         String uri = "https://www.cnblogs.com/biehongli";
     33         HttpGet httpGet = new HttpGet(uri);
     34         // 设置请求头消息 User-Agent 模拟浏览器
     35         httpGet.setHeader("User-Agent", UserAgent);
     36 
     37         // 定义一个可响应的实例对象。
     38         CloseableHttpResponse response = null;
     39         try {
     40             // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。
     41             response = httpClient.execute(httpGet);
     42             // 获取到响应的状态
     43             StatusLine statusLine = response.getStatusLine();
     44             System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode());
     45         } catch (ClientProtocolException e) {
     46             // http协议异常
     47             e.printStackTrace();
     48         } catch (IOException e) {
     49             // io异常
     50             e.printStackTrace();
     51         }
     52         // 第四步,获取到返回的实体对象
     53         HttpEntity entity = response.getEntity();
     54         // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西
     55         Header contentType = entity.getContentType();
     56         // 打印响应信息
     57         System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue());
     58 
     59         // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码
     60         String result = null;
     61         try {
     62             result = EntityUtils.toString(entity, "UTF-8");
     63         } catch (ParseException e) {
     64             e.printStackTrace();
     65         } catch (IOException e) {
     66             e.printStackTrace();
     67         }
     68         // 打印请求返回的结果
     69         // System.out.println(result.toString());
     70 
     71         // 讲获取到网页转换成为jsoup进行处理,返回结果为Document文档
     72         Document document = Jsoup.parse(result);
     73         Elements elements = document.getElementsByTag("title");
     74         Element element = elements.get(0);
     75         System.out.println("获取到的标题內容: " + element.text().toString());
     76 
     77         // 通过选择器查找所有博客链接DOM,获取到自己的博客题目名称内容
     78         // 使用Jsoup的选择器
     79         Elements select = document.select("#centercontent .day .postTitle .postTitle2");
     80         for (Element e : select) {
     81             System.out.println("博客标题:" + e.text());
     82         }
     83 
     84         // 带有href属性的a元素
     85         Elements selectHref = document.select(".postTitle a[href]");
     86         for (Element e : selectHref) {
     87             System.out.println("博客标题:" + e.text());
     88         }
     89 
     90         // 查找扩展名为.png的图片DOM节点
     91         Elements imgElements = document.select("img[src$=.png]");
     92         for (Element e : imgElements) {
     93             System.out.println(e.toString());
     94         }
     95 
     96         // 获取tag是title的所有DOM元素
     97         Element first = document.getElementsByTag("title").first();
     98         String title = first.text(); // 返回元素的文本
     99         System.out.println("网页标题是:" + title);
    100 
    101         // 第五步,关闭流,释放资源
    102         try {
    103             response.close();
    104             httpClient.close();
    105         } catch (IOException e) {
    106             e.printStackTrace();
    107         }
    108     }
    109 
    110     public static void main(String[] args) {
    111         HttpClientToJsoup.httpGetRequest();
    112     }
    113 
    114 }

    6、使用选择器语法查找元素,Jsoup elements对象支持类似于CSS (或jquery)的选择器语法,来实现非常强大和灵活的查找功能。这个select 方法在Document, Element,或Elements对象中都可以使用。且是上下文相关的,因此可实现指定元素的过滤,或者链式选择访问。Select方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。如下所示:

      1 package com.bie.jsoup;
      2 
      3 import java.io.IOException;
      4 
      5 import org.apache.http.Header;
      6 import org.apache.http.HttpEntity;
      7 import org.apache.http.ParseException;
      8 import org.apache.http.StatusLine;
      9 import org.apache.http.client.ClientProtocolException;
     10 import org.apache.http.client.methods.CloseableHttpResponse;
     11 import org.apache.http.client.methods.HttpGet;
     12 import org.apache.http.impl.client.CloseableHttpClient;
     13 import org.apache.http.impl.client.HttpClients;
     14 import org.apache.http.util.EntityUtils;
     15 import org.jsoup.Jsoup;
     16 import org.jsoup.nodes.Document;
     17 import org.jsoup.nodes.Element;
     18 import org.jsoup.select.Elements;
     19 
     20 public class HttpClientToJsoup {
     21 
     22     // 设置请求头消息 User-Agent 模拟浏览器
     23     private static String UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0";
     24 
     25     /**
     26      * HttpGet请求操作
     27      */
     28     public static void httpGetRequest() {
     29         // 第一步,获取到httpClient客户端实例,获取到一个可关闭的httpClient客户端实例。
     30         CloseableHttpClient httpClient = HttpClients.createDefault();
     31         // 第二步,创建HttpGet或者HttpPost实例。
     32         String uri = "https://www.cnblogs.com/biehongli";
     33         HttpGet httpGet = new HttpGet(uri);
     34         // 设置请求头消息 User-Agent 模拟浏览器
     35         httpGet.setHeader("User-Agent", UserAgent);
     36 
     37         // 定义一个可响应的实例对象。
     38         CloseableHttpResponse response = null;
     39         try {
     40             // 第三步,发布一个请求,使用httpClient实例发送一个http协议的Get请求。
     41             response = httpClient.execute(httpGet);
     42             // 获取到响应的状态
     43             StatusLine statusLine = response.getStatusLine();
     44             System.out.println("响应状态: " + statusLine.toString() + ", 响应码: " + statusLine.getStatusCode());
     45         } catch (ClientProtocolException e) {
     46             // http协议异常
     47             e.printStackTrace();
     48         } catch (IOException e) {
     49             // io异常
     50             e.printStackTrace();
     51         }
     52         // 第四步,获取到返回的实体对象
     53         HttpEntity entity = response.getEntity();
     54         // 获取响应内容类型 Content-Type,获取到响应类型,从而过滤一些不想要的东西
     55         Header contentType = entity.getContentType();
     56         // 打印响应信息
     57         System.out.println("name : " + contentType.getName() + " , value: " + contentType.getValue());
     58 
     59         // 将返回结果转换为字符串进行查看(网页内容),参数一是请求返回的entity,参数二是字符集编码
     60         String result = null;
     61         try {
     62             result = EntityUtils.toString(entity, "UTF-8");
     63         } catch (ParseException e) {
     64             e.printStackTrace();
     65         } catch (IOException e) {
     66             e.printStackTrace();
     67         }
     68         // 打印请求返回的结果
     69         // System.out.println(result.toString());
     70 
     71         // 讲获取到网页转换成为jsoup进行处理,返回结果为Document文档
     72         Document document = Jsoup.parse(result);
     73 
     74         // Jsoup 使用selector选择器
     75         Elements linkElements = document.select("#centercontent .day .postTitle .postTitle2"); // 通过选择器查找所有博客链接DOM
     76         for (Element e : linkElements) {
     77             System.out.println("博客标题:" + e.text());
     78             System.out.println("博客地址:" + e.attr("href"));
     79             // System.out.println("target:" + e.attr("target"));
     80         }
     81 
     82         // Jsoup 使用selector选择器
     83         Element linkElement = document.select(".postTitle2").first();
     84         System.out.println("纯文本内容:" + linkElement.text());
     85         System.out.println("Html内容:" + linkElement.html());
     86 
     87         // 第五步,关闭流,释放资源
     88         try {
     89             response.close();
     90             httpClient.close();
     91         } catch (IOException e) {
     92             e.printStackTrace();
     93         }
     94     }
     95 
     96     public static void main(String[] args) {
     97         HttpClientToJsoup.httpGetRequest();
     98     }
     99 
    100 }
     1 1、Selector选择器概述,如下所示:
     2 1)、tagname: 通过标签查找元素,比如:a。
     3 2)、ns|tag: 通过标签在命名空间查找元素,比如:可以用 fb|name 语法来查找 <fb:name> 元素。
     4 3)、#id: 通过ID查找元素,比如:#logo。
     5 4)、.class: 通过class名称查找元素,比如:.masthead。
     6 5)、[attribute]: 利用属性查找元素,比如:[href]。
     7 6)、[attr=value]: 利用属性值来查找元素,比如:[width=500]。
     8 
     9 
    10 // 案例使用,使用选择器
    11 // tagname: 通过标签查找元素,比如:a
    12 str = doc.select("a").first().text();
    13 
    14 // ns|tag: 通过标签在命名空间查找元素,比如:可以用 fb|name 语法来查找 <fb:name> 元素
    15 str = doc.select("jsoup|li").first().text();
    16 
    17 // #id: 通过ID查找元素,比如:#logo
    18 str = doc.select("#auto-header-fenzhan").first().text();
    19 
    20 // .class: 通过class名称查找元素,比如:.masthead
    21 str = doc.select(".orangelink").first().text();
    22 
    23 // [attribute]: 利用属性查找元素,比如:[href]
    24 str = doc.select("[abc]").first().text();
    25 
    26 // [attr=value]: 利用属性值来查找元素,比如:[width=500]
    27 str = doc.select("[class=vlli]").first().text();
    28 
    29 
    30 2、Selector选择器组合使用,如下所示:
    31 1)、el#id: 元素+ID,比如: div#logo。
    32 2)、el.class: 元素+class,比如: div.masthead。
    33 3)、el[attr]: 元素+属性名,比如: a[href]。
    34 4)、任意组合,比如:a[href].highlight。
    35 5)、ancestor child: 查找某个元素下子元素,比如:.body p 查找"body"下的所有 p。
    36 6)、parent > child: 查找某个父元素下的直接子元素,比如:div.content > p 查找 p。
    37 7)、parent > * 查找某个父元素下所有直接子元素。
    38 
    39 
    40 // 案例使用,组合选择器
    41 // el#id: 元素+ID,比如: div#logo
    42 str = doc.select("li#auto-header-fenzhan").first().text();
    43 
    44 // el.class: 元素+class,比如: div.masthead
    45 str = doc.select("a.greylink").first().text();
    46 
    47 // el[attr]: 元素+属性,比如: a[href]
    48 str = doc.select("a[href]").first().attr("href");
    49 
    50 // 任意组合,比如:a[href].highlight
    51 str = doc.select("a[href].greylink").first().attr("href");
    52 
    53 // ancestor child: 查找某个元素下子元素,比如:可以用.body p 查找"body"下的所有 p
    54 str = doc.select("div.mini-left a").text();
    55 
    56 // parent > child: 查找某个父元素下的直接子元素,比如:div.content > p 查找 p
    57 str = doc.select("div.mini-left ul > li").text();
    58 
    59 // parent > * 查找某个父元素下所有直接子元素
    60 Elements elements = doc.select("div.mini-left > *");
    61 for (Element ele : elements) {
    62     System.out.println(ele.tagName());
    63 }
  • 相关阅读:
    普通线程类获取service,controller等spring容器类
    java拦截器获取请求完整参数
    分享几个免费IP地址查询API接口
    echarts热力地图
    echarts ajax请求demo
    mysql统计前24小时数据没有补0
    java获取来访者mac信息
    java获取本机mac物理地址
    mysql5.7以上基本配置
    springboot拦截异常信息发送邮件提醒
  • 原文地址:https://www.cnblogs.com/biehongli/p/14059977.html
Copyright © 2011-2022 走看看