最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 爬蟲工具Jsoup詳解

 更新時間:2017年05月11日 09:55:35   作者:Smile_Miracle  
這篇文章主要介紹了 Java 爬蟲工具Jsoup詳解的相關(guān)資料,需要的朋友可以參考下

 Java 爬蟲工具Jsoup詳解

Jsoup是一款 Java 的 HTML 解析器,可直接解析某個 URL 地址、HTML 文本內(nèi)容。它提供了一套非常省力的 API,可通過 DOM,CSS 以及類似于 jQuery 的操作方法來取出和操作數(shù)據(jù)。

jsoup 的主要功能如下:

1. 從一個 URL,文件或字符串中解析 HTML;
2. 使用 DOM 或 CSS 選擇器來查找、取出數(shù)據(jù);
3. 可操作 HTML 元素、屬性、文本;

jsoup 是基于 MIT 協(xié)議發(fā)布的,可放心使用于商業(yè)項目。

jsoup 可以從包括字符串、URL 地址以及本地文件來加載 HTML 文檔,并生成 Document 對象實例。

簡單而言,Jsoup就是先取html頁面代碼然后解析這些頁面通過Jsoup攜帶的滿足我們絕大多數(shù)需求的各種選擇器從這個頁面中獲取我們所需要的重要數(shù)據(jù)的一款功能強大的html解析器,但也只是相對而言,這里的頁面這是死的靜態(tài)頁面,如果你想獲取動態(tài)生成的頁面數(shù)據(jù)那么你得用到其他的java 爬蟲技術(shù),我會不定時更新這些技術(shù)一起探討。下面我們來具體談?wù)勅绾芜\用Jsoup

一、如何取頁面

Jsoup提供了用來解析html頁面的方法 parse(),我們通過解析它可以獲取整個頁面的dom對象,通過這個對象來獲取你所需要的頁面所須有的參數(shù)。獲取頁面的方法有很多,這里就簡單的列舉幾個:

① 通過Jsoup攜帶的connect()方法

String htmlPage = Jsoup.connect("https://www.baidu.com").get().toString();

這個方法說需要的參數(shù)就是一個String類型的url鏈接,但是你的注意把這些鏈接的protrol加上,以免問題, 其實這個方法解決了我們很多問題,我們完全可以把Jsoup解析html抽取成一段通用工具類,然后通過改變拼接的url參數(shù)獲取到很多我們想要的東西,舉個例子:京東和淘寶的商品鏈接都是固定的,通過改變其三方商品ID來獲取商品詳情參數(shù)。

String url = "https://item.jd.com/11476104681.html";

完全可以替換成

String url = "https://item.jd.com/"+skuId+".html";

通過改變他的三方商品ID你就可以獲取這個頁面一些基本數(shù)據(jù),像商品的圖片和標(biāo)題什么的都可以輕松獲取,而價格因為做了一些相關(guān)方面的處理得動態(tài)的獲取,這里先不做說明,后面慢慢會講解。

②通過httpclient直接獲取這個頁面的靜態(tài)頁面

先貼一部分httpclient獲取頁面工具


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
/**
 * HTTP請求工具類.
 * @author LuoLong
 * @since 20150513
 *
 */
public class HttpClientUtils {
  /**
   * post方式請求.
   * @param url 請求地址.
   * @param params 請求參數(shù)
   * @return String
   */
  public static String post(String url, Map<String, String> params) {
    DefaultHttpClient httpclient = new DefaultHttpClient();
    String body = null;

    HttpPost post = postForm(url, params);

    body = invoke(httpclient, post);

    httpclient.getConnectionManager().shutdown();

    return body;
  }

  /**
   * get方式請求.
   * @param url 請求地址.
   * @return String
   */
  public static String get(String url) {
    DefaultHttpClient httpclient = new DefaultHttpClient();
    String body = null;

    HttpGet get = new HttpGet(url);
    body = invoke(httpclient, get);

    httpclient.getConnectionManager().shutdown();

    return body;
  }
  /**
   * 請求方法.
   * @param httpclient DefaultHttpClient.
   * @param httpost 請求方式.
   * @return String
   */
  private static String invoke(DefaultHttpClient httpclient,
      HttpUriRequest httpost) {

    HttpResponse response = sendRequest(httpclient, httpost);
    String body = paseResponse(response);

    return body;
  }

  /**
   * 
   * @param response
   * @return
   */
  @SuppressWarnings({ "deprecation", "unused" })
  private static String paseResponse(HttpResponse response) {
    HttpEntity entity = response.getEntity();

    String charset = EntityUtils.getContentCharSet(entity);

    String body = null;
    try {
      body = EntityUtils.toString(entity);
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return body;
  }

  private static HttpResponse sendRequest(DefaultHttpClient httpclient,
      HttpUriRequest httpost) {
    HttpResponse response = null;

    try {
      response = httpclient.execute(httpost);
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return response;
  }

  @SuppressWarnings("deprecation")
  private static HttpPost postForm(String url, Map<String, String> params) {

    HttpPost httpost = new HttpPost(url);
    List<NameValuePair> nvps = new ArrayList<NameValuePair>();

    Set<String> keySet = params.keySet();
    for (String key : keySet) {
      nvps.add(new BasicNameValuePair(key, params.get(key)));
    }
    try {
      httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    return httpost;
  }
}

通過get()方法就可以獲取html頁面的String類型數(shù)據(jù)

String content = HttpClientUtils.get(url);
或者你可以直接把頁面下載到本地,然后解析此html文檔獲取
File input = new File(FilePath);
Document doc = Jsoup.parse(input, "UTF-8", url);

二、解析頁面獲取需要的數(shù)據(jù)

當(dāng)你獲取到頁面的dom對象后,那么下面的操作就非常簡單了,你只需要通過操作這個dom對象來獲取頁面所有的靜態(tài)資源,動態(tài)加載的資源不在此列,后面在做講解。

先貼一段百度網(wǎng)頁的源代碼:

 </form>
    <div id="m"></div>
   </div>
   </div>
   <div id="u">
   <a class="toindex" href="/" rel="external nofollow" >百度首頁</a>
   <a href="javascript:;" rel="external nofollow" name="tj_settingicon" class="pf">設(shè)置<i class="c-icon c-icon-triangle-down"></i></a>
   <a  rel="external nofollow" rel="external nofollow" name="tj_login" class="lb" onclick="return false;">登錄</a>
   </div>
   <div id="u1">
   <a  rel="external nofollow" name="tj_trnews" class="mnav">新聞</a>
   <a  rel="external nofollow" name="tj_trhao123" class="mnav">hao123</a>
   <a  rel="external nofollow" name="tj_trmap" class="mnav">地圖</a>
   <a  rel="external nofollow" name="tj_trvideo" class="mnav">視頻</a>
   <a  rel="external nofollow" name="tj_trtieba" class="mnav">貼吧</a>
   <a  rel="external nofollow" name="tj_trxueshu" class="mnav">學(xué)術(shù)</a>
   <a  rel="external nofollow" rel="external nofollow" name="tj_login" class="lb" onclick="return false;">登錄</a>
   <a  rel="external nofollow" name="tj_settingicon" class="pf">設(shè)置</a>
   <a  rel="external nofollow" name="tj_briicon" class="bri" style="display: block;">更多產(chǎn)品</a>
   </div>
  </div>
  </div> 
  <div class="s_tab" id="s_tab"> 
  <b>網(wǎng)頁</b>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'news'})">新聞</a>
  <a  rel="external nofollow" wdfield="kw" onmousedown="return c({'fm':'tab','tab':'tieba'})">貼吧</a>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'zhidao'})">知道</a>
  <a  rel="external nofollow" wdfield="key" onmousedown="return c({'fm':'tab','tab':'music'})">音樂</a>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'pic'})">圖片</a>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'video'})">視頻</a>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'map'})">地圖</a>
  <a  rel="external nofollow" wdfield="word" onmousedown="return c({'fm':'tab','tab':'wenku'})">文庫</a>
  <a  rel="external nofollow" onmousedown="return c({'fm':'tab','tab':'more'})">更多&raquo;</a> 
  </div> 
  <div class="qrcodeCon"> 
  <div id="qrcode"> 
   <div class="qrcode-item qrcode-item-1"> 
   <div class="qrcode-img"></div> 
   <div class="qrcode-text"> 
    <p><b>手機百度</b></p> 
   </div> 
   </div> 
  </div> 
  </div> 
  <div id="ftCon"> 
  <div class="ftCon-Wrapper">
   <div id="ftConw">
   <p id="lh"><a id="setf"  rel="external nofollow" onmousedown="return ns_c({'fm':'behs','tab':'favorites','pos':0})" target="_blank">把百度設(shè)為主頁</a><a onmousedown="return ns_c({'fm':'behs','tab':'tj_about'})"  rel="external nofollow" >關(guān)于百度</a><a onmousedown="return ns_c({'fm':'behs','tab':'tj_about_en'})"  rel="external nofollow" >About&nbsp;&nbsp;Baidu</a><a onmousedown="return ns_c({'fm':'behs','tab':'tj_tuiguang'})"  rel="external nofollow" >百度推廣</a></p>
   <p id="cp">&copy;2017&nbsp;Baidu&nbsp;<a  rel="external nofollow" onmousedown="return ns_c({'fm':'behs','tab':'tj_duty'})">使用百度前必讀</a>&nbsp;<a  rel="external nofollow" class="cp-feedback" onmousedown="return ns_c({'fm':'behs','tab':'tj_homefb'})">意見反饋</a>&nbsp;京ICP證030173號&nbsp;<i class="c-icon-icrlogo"></i>&nbsp;<a id="jgwab" target="_blank"  rel="external nofollow" >京公網(wǎng)安備11000002000001號</a>&nbsp;<i class="c-icon-jgwablogo"></i></p>
   </div>
  </div>
  </div> 
  <div id="wrapper_wrapper"> 
  </div> 
 </div> 
 <div class="c-tips-container" id="c-tips-container"></div> 

在貼上Jsoup自身攜帶的常用的幾個獲取dom對象具體元素的方法:

method              description
getElementsByClass()       通過Class屬性來定位元素,獲取的是所有帶這個class屬性的集合
getElementsByTag();       通過標(biāo)簽名字來定位元素,獲取的是所有帶有這個標(biāo)簽名字的元素結(jié)合 
getElementById();        通過標(biāo)簽的ID來定位元素,這個是精準(zhǔn)定位,因為頁面的ID基本不會重復(fù)
getElementsByAttributeValue();  通過屬性和屬性名來定位元素,獲取的也是一個滿足條件的集合;
getElementsByAttributeValueMatching()    通過正則匹配屬性  

比如說我現(xiàn)在要獲取百度首頁這個title,那么我們得先確定這玩意在哪,通過查看我們發(fā)現(xiàn)它是id=”u”的div標(biāo)簽的一個子元素,那么不管那么多我們先通過這個Id取到這個對象然后在獲取這個Title,下面是具體操作

//獲取頁面對象
String startPage="https://www.baidu.com";

Document document = Jsoup.connect(startPage).userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36").get();

//定位元素父級
Element parentElement = document.getElementById("u");

//定位具體元素
Element titleElement = parentElement.getElementsByTag("a").get(0);

//獲取所需數(shù)據(jù)
String title = titleElement.text();

System.out.println(title);

又或者我需要獲取頁面《手機百度》這個數(shù)據(jù):

String startPage="https://www.baidu.com";

Document document = Jsoup.connect(startPage).userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36").get();

Element elementById = document.getElementById("qrcode");

String text = elementById.getAllElements().get(0).getAllElements().get(1).getElementsByTag("b").text();

System.out.println(text);

這就是一個很簡單的爬蟲編寫工具,Jsoup功能很強大,對直接爬取沒有動態(tài)加載的靜態(tài)資源頁面再適合不過。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Java String類字符串的理解與認(rèn)知

    Java String類字符串的理解與認(rèn)知

    String字符串和char字符不同,char使用單引號,只能表示一個字符,字符串就是一段文本。String是個類。這個類使用final修飾,所以這個類是不可以繼承擴充和修改它的方法的
    2021-10-10
  • 一個Java配置文件加密解密工具類分享

    一個Java配置文件加密解密工具類分享

    在 JavaEE 配置文件中,例如 XML 或者 properties 文件,由于某些敏感信息不希望普通人員看見,則可以采用加密的方式存儲,程序讀取后進行解密
    2014-04-04
  • Java設(shè)計模式中的迭代器模式詳解

    Java設(shè)計模式中的迭代器模式詳解

    迭代器模式官方解釋就是提供一個對象來順序訪問聚合對象中的一系列數(shù)據(jù),而不暴露聚合對象的內(nèi)部表示。何為聚合對象呢?最典型的就是集合類。大白話也就是,集合中的數(shù)據(jù)是私有的,集合中不應(yīng)該提供直接遍歷的方法,要定義一個新的對象用于訪問這個集合
    2023-02-02
  • SpringBoot操作Jedis案例代碼

    SpringBoot操作Jedis案例代碼

    這篇文章主要介紹了SpringBoot操作Jedis案例代碼,代碼部分包括pom依賴、配置相關(guān)參數(shù)、JedisPool的設(shè)置,代碼簡單易懂對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java實現(xiàn)的兩種常見簡單查找算法示例【快速查找與二分查找】

    Java實現(xiàn)的兩種常見簡單查找算法示例【快速查找與二分查找】

    這篇文章主要介紹了Java實現(xiàn)的兩種常見簡單查找算法,結(jié)合具體實例形式分析了java快速查找與二分查找的原理與簡單實現(xiàn)技巧,需要的朋友可以參考下
    2017-09-09
  • SpringBoot自定義定時任務(wù)的實現(xiàn)示例

    SpringBoot自定義定時任務(wù)的實現(xiàn)示例

    本文主要介紹了SpringBoot自定義定時任務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Java實現(xiàn)讀取Excel文件功能(EasyExcel初使用)

    Java實現(xiàn)讀取Excel文件功能(EasyExcel初使用)

    EasyExcel是一款基于Java語言的開源Excel解析工具,可以幫助我們快速、高效地讀取和寫入Excel文件,這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)讀取Excel文件功能的相關(guān)資料,使用的是EasyExcel,需要的朋友可以參考下
    2024-07-07
  • 全面了解servlet中cookie的使用方法

    全面了解servlet中cookie的使用方法

    下面小編就為大家?guī)硪黄媪私鈙ervlet中cookie的使用方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • MyBatis存儲過程、MyBatis分頁、MyBatis一對多增刪改查操作

    MyBatis存儲過程、MyBatis分頁、MyBatis一對多增刪改查操作

    本文通過一段代碼給大家介紹了MyBatis存儲過程、MyBatis分頁、MyBatis一對多增刪改查操作,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-11-11
  • springboot-dubbo cannot be cast to問題及解決

    springboot-dubbo cannot be cast to問題及解決

    這篇文章主要介紹了springboot-dubbo cannot be cast to問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

嘉荫县| 临江市| 武城县| 安图县| 巴林右旗| 湟中县| 凌海市| 上高县| 大庆市| 大厂| 清新县| 日土县| 万山特区| 读书| 湘潭县| 昌图县| 务川| 上林县| 高碑店市| 洮南市| 炉霍县| 龙里县| 河池市| 唐河县| 洛川县| 大安市| 普格县| 固安县| 凤冈县| 邳州市| 浠水县| 长治县| 濉溪县| 竹山县| 道真| 阜宁县| 建宁县| 文安县| 娄烦县| 宁安市| 东辽县|