歡迎您光臨本站 註冊首頁

springBoot+webMagic實現網站爬蟲的實例代碼

←手機掃碼閱讀     zmcjlove @ 2020-06-10 , reply:0

前端時間公司項目需要抓取各類數據,py玩的不6,只好研究Java爬蟲方案,做一個總結。

開發環境:
 

springBoot 2.2.6、jdk1.8。

1、導入依賴
 

  us.codecraftwebmagic-core0.7.3  -->  -->  org.slf4j-->  slf4j-log4j12-->  -->  -->us.codecraftwebmagic-extension0.7.3com.google.guavaguava16.0

 

話不多說,直接上代碼。

基礎案例
 

下面代碼說明以一個類似列表的頁面為例

  package com.crawler.project.proTask;    import com.alibaba.fastjson.JSONObject;  import org.springframework.scheduling.annotation.Scheduled;  import us.codecraft.webmagic.Page;  import us.codecraft.webmagic.Site;  import us.codecraft.webmagic.Spider;  import us.codecraft.webmagic.processor.PageProcessor;  import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;  import us.codecraft.webmagic.scheduler.QueueScheduler;  import us.codecraft.webmagic.selector.Selectable;    import java.util.List;    public class TaskProcessor implements PageProcessor {     /*   * 此方法為爬蟲業務實現   * */   @Override   public void process(Page page) {      //1、爬蟲任務獲取到一個page 解析page上的列表    Listlist = page.getHtml().css("css selector").nodes();    if (list.size() > 0){//說明為列表頁面、需要解析列表中每個元素的鏈接,存入待獲取page隊列中     for (Selectable selectable : list) {      //遍歷集合,將每個元素鏈接存入待獲取page隊列中      page.addTargetRequest(selectable.links().toString());     }     //同時將下一頁的url存入隊列中     page.addTargetRequest("下一頁的url");    }else {     //此時為列表中單個元素對應的詳情頁     //在自定義方法中處理詳細頁,獲取需要的數據進行處理。     handle(page);    }   }     private void handle(Page page) {      //例如 處理後的數據為一個JSONObject對象    JSONObject tmp = new JSONObject();      //將這個tmp交由自定義的TaskPipline類處理,若未自定義Pipline並設置到Spider參數中,框架會默認將tmp打印到控制檯。    page.putField("obj",tmp);   }     /*   * 此方法為配置爬蟲過程的一些參數   * */   private Site site = Site.me()     .setCharset("UTF-8")     .setTimeOut(60 * 1000)     .setRetrySleepTime(60 * 1000)     .setCycleRetryTimes(5);   @Override   public Site getSite() {    return site;   }     /*   設置定時任務,執行爬蟲任務   * */   @Scheduled(initialDelay = 1 * 1000,fixedDelay = 2 * 1000)   public void process(){    System.out.println("開始執行爬蟲抓取任務");    Spider.create(new TaskProcessor())//注意這裡的類名要和當前類名對應      .addUrl("起始頁url")      .addPipeline(new TaskPipeline()) //此處課自定義 數據處理類 (在handle()方法中有);      .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))      .thread(3)//此處設置線程數量(不宜過多,最好和列表頁中列表元素數量一致)      .run();   }  }

 

  package com.crawler.project.proTask;    import com.alibaba.fastjson.JSON;  import com.alibaba.fastjson.JSONObject;  import us.codecraft.webmagic.ResultItems;  import us.codecraft.webmagic.Task;  import us.codecraft.webmagic.pipeline.Pipeline;    public class TaskPipeline implements Pipeline {   @Override   public void process(ResultItems resultItems, Task task) {    if (resultItems.getAll() .size() > 0){     Object obj = resultItems.getAll().get("obj");     JSONObject jsonObject = JSON.parseObject(obj.toString());     //獲取到JSONObject對象下面可進行自定義的業務處理。    }   }  }

 

特殊情況一
 

需根據鏈接下載圖片或文件

eg:在上面說到的詳情頁中含有iframe。

1、首先獲取iframe的src

  //獲得iframe的src (這裡要注意獲得的src是絕對路徑還是相對路徑,相對路徑需要拼接主站點url)  String src = html.css("css selector", "src").toString();    //採用jsoup解析  Document document = Jsoup.parse(new URL(src),1000);  //獲得需要的元素  Element ele = document.select("css selector").last();  //獲取需要下載的文件的鏈接  String downUrl = ele.attr("href");  //根據鏈接下載文件 返回一個文件的名稱  String fileName = downloadFile(downUrl);

 

  //通過url下載文件  public String downloadFile(String fileUrl) throws FileNotFoundException{   try{     URL httpUrl = new URL(fileUrl);     String fileName = UUID.randomUUID().toString() + ".mp3";     File file = new File(this.STATIC_FILEPATH + fileName);     System.out.println("============保存文件方法被調用===============");     FileUtils.copyURLToFile(httpUrl,file);     return fileName;    }catch (Exception e){     e.printStackTrace();     return null;    }  }

 

特殊情況二
 

有些https站點 無法直接使用WebMagic默認的下載器下載,此時我們可以根據站點ssl類型修改下載器。

在項目中創建一個包用於存放自定義(修改)的下載器類

(!!!摘自webMagic框架中HttpClientDownloader,基於此類修改!!!)

  /*  此方法中需要傳入一個自定義的生成器(HttpClientGenerator)  */    package com.crawler.project.spider_download;    import org.apache.commons.io.IOUtils;  import org.apache.http.HttpResponse;  import org.apache.http.client.methods.CloseableHttpResponse;  import org.apache.http.impl.client.CloseableHttpClient;  import org.apache.http.util.EntityUtils;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import us.codecraft.webmagic.Page;  import us.codecraft.webmagic.Request;  import us.codecraft.webmagic.Site;  import us.codecraft.webmagic.Task;  import us.codecraft.webmagic.downloader.AbstractDownloader;  import us.codecraft.webmagic.downloader.HttpClientRequestContext;  import us.codecraft.webmagic.downloader.HttpUriRequestConverter;  import us.codecraft.webmagic.proxy.Proxy;  import us.codecraft.webmagic.proxy.ProxyProvider;  import us.codecraft.webmagic.selector.PlainText;  import us.codecraft.webmagic.utils.CharsetUtils;  import us.codecraft.webmagic.utils.HttpClientUtils;    import java.io.IOException;  import java.nio.charset.Charset;  import java.util.HashMap;  import java.util.Map;      /**   * The http downloader based on HttpClient.   *   * @author code4crafter@gmail.com 
   * @since 0.1.0   */  public class HttpClientDownloader extends AbstractDownloader {     private Logger logger = LoggerFactory.getLogger(getClass());     private final Map

 

然後在自定義的HttpClientGenerator類中修改有關ssl的參數

(!!!摘自webMagic框架中HttpClientGenerator,基於此類修改!!!)

  /*  自定義的HttpClientGenerator生成器  */    package com.sealion_crawler.project.spider_download;    import org.apache.http.HttpException;  import org.apache.http.HttpRequest;  import org.apache.http.HttpRequestInterceptor;  import org.apache.http.client.CookieStore;  import org.apache.http.config.Registry;  import org.apache.http.config.RegistryBuilder;  import org.apache.http.config.SocketConfig;  import org.apache.http.conn.socket.ConnectionSocketFactory;  import org.apache.http.conn.socket.PlainConnectionSocketFactory;  import org.apache.http.conn.ssl.DefaultHostnameVerifier;  import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  import org.apache.http.impl.client.*;  import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;  import org.apache.http.impl.cookie.BasicClientCookie;  import org.apache.http.protocol.HttpContext;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import us.codecraft.webmagic.Site;  import us.codecraft.webmagic.downloader.CustomRedirectStrategy;    import javax.net.ssl.SSLContext;  import javax.net.ssl.TrustManager;  import javax.net.ssl.X509TrustManager;  import java.io.IOException;  import java.security.KeyManagementException;  import java.security.NoSuchAlgorithmException;  import java.security.cert.CertificateException;  import java.security.cert.X509Certificate;  import java.util.Map;    /**   * @author code4crafter@gmail.com 
   * @since 0.4.0   */  public class HttpClientGenerator {      private transient Logger logger = LoggerFactory.getLogger(getClass());      private PoolingHttpClientConnectionManager connectionManager;     public HttpClientGenerator() {    Registry

 

好了,到這裡 基於WebMagic框架 實現爬蟲、包括jsoup的使用總結就到這裡的。

       


[zmcjlove ] springBoot+webMagic實現網站爬蟲的實例代碼已經有250次圍觀

http://coctec.com/docs/java/show-post-237837.html