<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          VW-CrawlerJava 爬蟲(chóng)框架

          聯(lián)合創(chuàng)作 · 2023-09-29 13:43

          VW-Crawler

          背景

          自己一直對(duì)爬蟲(chóng)比較感興趣,大學(xué)的畢業(yè)論文也是一個(gè)爬蟲(chóng)項(xiàng)目(爬教務(wù)處信息,然后做了個(gè)Android版教務(wù)管理系統(tǒng),還獲得了優(yōu)秀畢業(yè)設(shè)計(jì)的稱號(hào)),自那以后遇到自己感興趣的網(wǎng)站就會(huì)去抓一下。前段時(shí)間工作上需要一些JD信息,我就從網(wǎng)上找了個(gè)開(kāi)源的爬蟲(chóng)框架WebMagic,使用簡(jiǎn)單,易配置,功能也很強(qiáng)大,當(dāng)然了也有些網(wǎng)站的數(shù)據(jù)不適合使用。前前后后寫了不下十幾個(gè),慢慢的就想是不是可以把這些爬蟲(chóng)代碼再抽象出來(lái),做出一個(gè)簡(jiǎn)易的爬蟲(chóng)框架呢?于是就嘗試去看WebMagic的源碼,后來(lái)又發(fā)現(xiàn)了一個(gè)源碼比較容易解讀的爬蟲(chóng)框架XXL-CRAWLER,簡(jiǎn)單的分析了源碼之后,開(kāi)發(fā)自己一套爬蟲(chóng)框架的欲望更加強(qiáng)烈,于是在2017年底的時(shí)候就開(kāi)始了開(kāi)發(fā),中間斷斷續(xù)續(xù)得停了寫,寫了停。直到最近8月底的時(shí)候才算出了一個(gè)版本,然后順勢(shì)把它放到了Maven公服倉(cāng)庫(kù)上。一個(gè)人的力量很薄弱,要想完善這個(gè)爬蟲(chóng)的健壯性、可用性和易擴(kuò)展性還需要大家的力量!

          特點(diǎn)

          •  語(yǔ)言: Java開(kāi)發(fā),框架比較簡(jiǎn)單,多處使用的是接口編程,是學(xué)習(xí)Java不錯(cuò)的例子

          •  難度: 及其簡(jiǎn)單,配置一下,寫個(gè)解析邏輯,整理下保存方法,就OK了

          •  輕量: 使用Jsoup做默認(rèn)的下載器,依賴性較低

          •  線程: 可自主**設(shè)置線程**數(shù)抓取,提高抓取效率

          •  重試: 支持失敗重試,次數(shù)可以自定義

          •  代理: 支持配置**代理池**,默認(rèn)隨機(jī)使用代理IP,也可自定義算法獲取

          •  去重: **雙重去重**,默認(rèn)對(duì)URL去重,也可以定義第二層去重邏輯

          •  控制: 可**自主控制**是否需要解析頁(yè)面,減少資源的使用

          •  精準(zhǔn): 通過(guò)設(shè)置URL的正則來(lái)**精準(zhǔn)**的解析每一個(gè)URL

          •  擴(kuò)展: 幾乎每一個(gè)環(huán)節(jié)都可以自定義

          使用

          使用Maven

          http://search.maven.org上使用最新的版本
          在pom中引入

          <dependency>
              <groupId>com.github.vector4wang</groupId>
              <artifactId>vw-crawler</artifactId>
              <version>${last.version}</version>
          </dependency>

          離線使用

          可以在項(xiàng)目主頁(yè)的[release](https://github.com/vector4wang/vw-crawler/releases)下載最新版本jar,然后導(dǎo)入自己的項(xiàng)目中。

          步驟

          1.  配置參數(shù)

          2.  抽象正則

          3.  解析頁(yè)面

          4.  保存數(shù)據(jù)

          各環(huán)節(jié)均支持自定義

          示例

          抓取CSDN某用戶的博客內(nèi)容

          設(shè)置爬蟲(chóng)的基本配置,如User-Agent、起始地址、目標(biāo)頁(yè)面的url正則表達(dá)式、線程數(shù)和超時(shí)時(shí)間等

          new VWCrawler.Builder()
                  // 配置參數(shù)
                  .setHeader("User-Agent",
                          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36") // 設(shè)置請(qǐng)求頭
                  .setUrl("https://blog.csdn.net/qqhjqs") // 設(shè)置爬蟲(chóng)起始地址
                  .setThreadCount(10) // 設(shè)置幾個(gè)線程抓取數(shù)據(jù)
                  .setTimeOut(5000) // 設(shè)置超時(shí)時(shí)間
          
                  // 抽象正則
                  .setTargetUrlRex("https://blog.csdn.net/qqhjqs/article/details/[0-9]+") // 設(shè)置目標(biāo)頁(yè)面url的正則表達(dá)式
          
                  // 解析頁(yè)面
                  .setPageParser(new CrawlerService<Blog>() {
          
                      /**
                       * 有的url可能在某個(gè)場(chǎng)景下不需要可在此處理
                       * 默認(rèn)返回false,可以不做處理
                       * @param url 即將要抓取的url
                       * @return
                       */
                      @Override
                      public boolean isExist(String url) {
                          if ("https://blog.csdn.net/qqhjqs/article/details/79101846".equals(url)) {
                              return true;
                          }
                          return false;
                      }
          
                      /**
                       * 有的頁(yè)面有WAF,可以再真正解析前,做個(gè)判斷,遇到特殊標(biāo)志的直接可以跳過(guò)
                       * 默認(rèn)返回true,可以不做處理
                       * @param document 即將要解析的document
                       * @return
                       */
                      @Override
                      public boolean isContinue(Document document) {
                          if ("最近和未來(lái)要做的事 - CSDN博客".equals(document.title())) {
                              System.out.println("模擬遇到WAF此頁(yè)面不做解析");
                              return false;
                          }
                          return true;
                      }
          
                      /**
                       * 目標(biāo)頁(yè)面的doc對(duì)象,還有通過(guò)注解處理后的對(duì)象
                       * @param doc 文檔內(nèi)容
                       * @param pageObj 封裝的對(duì)象
                       */
                      @Override
                      public void parsePage(Document doc, Blog pageObj) {
                          // 可進(jìn)行二次處理
                          pageObj.setReadNum(pageObj.getReadNum().replace("閱讀數(shù):", ""));
                      }
          
          
                      // 保存數(shù)據(jù)
          
                      /**
                       * 可以做保存對(duì)象的處理
                       * @param pageObj 頁(yè)面對(duì)象
                       */
                      @Override
                      public void save(Blog pageObj) {
                          System.out.println("save blog summery: " + pageObj.toString());
                      }
                  }) // 自定義解析service
          
          
                  .build().start(); // 啟動(dòng)

          配置頁(yè)面數(shù)據(jù)對(duì)象的注解

          @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-title-box > h1", resultType = SelectType.TEXT)
          private String title;
          
          @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > span.time", dateFormat = "yyyy年MM月dd日 HH????ss")
          private Date lastUpdateDate;
          
          @CssSelector(selector = "#mainBox > main > div.blog-content-box > div.article-info-box > div > div > span", resultType = SelectType.TEXT)
          private String readNum;

          這里使用比較流行的注解方式,通過(guò)cssselector來(lái)獲取節(jié)點(diǎn)數(shù)據(jù)可通過(guò)resultType來(lái)指定填充的是text還是html。隨便配置一下,就能抓取一個(gè)頁(yè)面的數(shù)據(jù)

          new VWCrawler.Builder().setUrl("https://www.qiushibaike.com/").setPageParser(new CrawlerService() {
              @Override
              public void parsePage(Document doc, Object pageObj) {
                  System.out.println(doc.toString());
              }
          
              @Override
              public void save(Object pageObj) {
          
              }
          }).build().start();
          瀏覽 14
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲无码家庭乱伦 | 思瑞土豪视频大全 | 影音先锋乱伦电影 | 成人电影天天干 | 女人扒开腿让男人桶爽 |