国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

基于RxJava2實現的簡單圖片爬蟲的方法

2019-10-22 18:15:50
字體:
來源:轉載
供稿:網友

今年十月份以來,跟朋友嘗試導入一些圖片到tensorflow來生成模型,這就需要大量的圖片。剛開始我只寫了一個簡單的HttpClient程序來抓取圖片,后來為了通用性索性寫一個簡單的圖片爬蟲程序。它可以用于抓取單張圖片、多張圖片、某個網頁下的所有圖片、多個網頁下的所有圖片。

github地址:https://github.com/fengzhizi715/PicCrawler

這個爬蟲使用了HttpClient、RxJava2以及Java 8的一些特性。它支持一些簡單的定制,比如定制User-Agent、Referer、Cookies等。

一.下載安裝:

對于Java項目如果使用gradle構建,由于默認不是使用jcenter,需要在相應module的build.gradle中配置

repositories {  mavenCentral()  jcenter()}

Gradle:

compile 'com.cv4j.piccrawler:crawler:0.2.1'

Maven:

<dependency> <groupId>com.cv4j.piccrawler</groupId> <artifactId>crawler</artifactId> <version>0.2.1</version> <type>pom</type></dependency>

二.使用方法:

2.1 下載單張圖片

1、普通方式

    String url = "..."; // 圖片的地址    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .repeat(200) // 重復200次        .build()        .downloadPic(url);

在這里,timeOut()表示網絡請求的超時時間。fileStrategy()表示存放的目錄、文件使用的格式、生成的文件時使用何種策略。repeat()表示對該圖片請求重復的次數。

PicCrawler支持多種文件的生成策略,比如隨機生成文件名、從1開始自增長地生成文件名、生成指定的文件名等等。

下圖顯示了使用該程序對某驗證碼的圖片下載200次。

RxJava2,圖片爬蟲,簡單爬蟲,簡單爬蟲圖片

2、使用RxJava的方式下載

    String url = "..."; // 圖片的地址    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .repeat(200)        .build()        .downloadPicUseRx(url);

3、使用RxJava,下載之后的圖片還能做后續的處理

    String url = "..."; // 圖片的地址    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .repeat(200)        .build()        .downloadPicToFlowable(url)        .subscribe(new Consumer<File>() {          @Override          public void accept(File file) throws Exception {            // do something          }        });

在Consumer中,可以對文件做一些后續的處理。

2.2 下載多張圖片

    List<String> urls = ...; // 多張圖片地址的集合    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .build()        .downloadPics(urls);

2.3 下載某個網頁的全部圖片

    String url = "http://www.jianshu.com/u/4f2c483c12d8"; // 針對某一網址    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .build()        .downloadWebPageImages(url);

使用上面的程序,對我簡書主頁上的圖片進行抓取。

RxJava2,圖片爬蟲,簡單爬蟲,簡單爬蟲圖片

2.4 下載多個網頁的全部圖片

 

    List<String> urls = new ArrayList<>(); // 多個網頁的集合    urls.add("http://www.jianshu.com/u/4f2c483c12d8");    urls.add("https://toutiao.io/");    CrawlerClient.get()        .timeOut(6000)        .fileStrategy(new FileStrategy() {          @Override          public String filePath() {            return "temp";          }          @Override          public String picFormat() {            return "png";          }          @Override          public FileGenType genType() {            return FileGenType.AUTO_INCREMENT;          }        })        .build()        .downloadWebPageImages(urls);

下載個人簡書主頁上的圖以及開發者頭條的圖片。

RxJava2,圖片爬蟲,簡單爬蟲,簡單爬蟲圖片

三. 部分源碼解析

3.1 下載某個網頁的全部圖片

downloadWebPageImages()方法表示下載某個url的全部圖片。

  /**   * 下載整個網頁的全部圖片   * @param url   */  public void downloadWebPageImages(String url) {    Flowable.just(url)        .map(s->httpManager.createHttpWithGet(s))        .map(response->parseHtmlToImages(response))        .subscribe(urls -> downloadPics(urls),            throwable-> System.out.println(throwable.getMessage()));  }

downloadWebPageImages()分成三步:創建網絡請求、解析出當前頁面中包含的圖片路徑、下載這些圖片。

第一步,創建網絡請求使用了HttpClient。

  public CloseableHttpResponse createHttpWithGet(String url) {    // 獲取客戶端連接對象    CloseableHttpClient httpClient = getHttpClient();    // 創建Get請求對象    HttpGet httpGet = new HttpGet(url);    if (Preconditions.isNotBlank(httpParam)) {      Map<String,String> header = httpParam.getHeader();      if (Preconditions.isNotBlank(header)) {        for (String key : header.keySet()) {          httpGet.setHeader(key,header.get(key));        }      }    }    CloseableHttpResponse response = null;    // 執行請求    try {      response = httpClient.execute(httpGet);    } catch (IOException e) {      e.printStackTrace();    }    return response;  }

第二步,將返回的response轉換成String類型,使用jsoup將帶有圖片的鏈接全部過濾出來。

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

private List<String> parseHtmlToImages(CloseableHttpResponse response) {    // 獲取響應實體    HttpEntity entity = response.getEntity();    InputStream is = null;    String html = null;    try {      is = entity.getContent();      html = IOUtils.inputStream2String(is);    } catch (IOException e) {      e.printStackTrace();    }    Document doc = Jsoup.parse(html);    Elements media = doc.select("[src]");    List<String> urls = new ArrayList<>();    if (Preconditions.isNotBlank(media)) {      for (Element src : media) {        if (src.tagName().equals("img")) {          if (Preconditions.isNotBlank(src.attr("abs:src"))) { // 圖片的絕對路徑不為空            String picUrl = src.attr("abs:src");            log.info(picUrl);            urls.add(picUrl);          } else if (Preconditions.isNotBlank(src.attr("src"))){ // 圖片的相對路徑不為空            String picUrl = src.attr("src").replace("//","");            picUrl = "http://"+Utils.tryToEscapeUrl(picUrl);            log.info(picUrl);            urls.add(picUrl);          }        }      }    }    if (response != null) {      try {        EntityUtils.consume(response.getEntity());        response.close();      } catch (IOException e) {        System.err.println("釋放鏈接錯誤");        e.printStackTrace();      }    }    return urls;  }

第三步,下載這些圖片使用了Java 8的CompletableFuture。CompletableFuture是Java 8新增的用于異步處理的類,而且CompletableFuture的性能也好于傳統的Future。

  /**   * 下載多張圖片   * @param urls   */  public void downloadPics(List<String> urls) {    if (Preconditions.isNotBlank(urls)) {      urls.stream().parallel().forEach(url->{        try {          CompletableFuture.runAsync(() -> downloadPic(url)).get();        } catch (InterruptedException e) {          e.printStackTrace();        } catch (ExecutionException e) {          e.printStackTrace();        }      });    }  }

3.2 下載多個網頁的全部圖片

downloadWebPageImages()方法還支持傳List集合,表示多個網頁的地址。

  /**   * 下載多個網頁的全部圖片   * @param urls   */  public void downloadWebPageImages(List<String> urls) {    if (Preconditions.isNotBlank(urls)) {      Flowable.fromIterable(urls)          .parallel()          .map(url->httpManager.createHttpWithGet(url))          .map(response->parseHtmlToImages(response))          .sequential()          .subscribe(list -> downloadPics(list),              throwable-> System.out.println(throwable.getMessage()));    }  }

在這里其實用到了ParallelFlowable,因為parallel()可以把Flowable轉成ParallelFlowable。

總結

PicCrawler 是一個簡單的圖片爬蟲,目前基本可以滿足我的需求。未來要是有新的需求,我會不斷添加功能。

在做PicCrawler時,其實還做了一個ProxyPool用于獲取可用代理池的庫,它也是基于RxJava2實現的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赣榆县| 抚松县| 晋城| 兴和县| 泸州市| 灵川县| 航空| 西和县| 太湖县| 喜德县| 塔城市| 北安市| 广河县| 茂名市| 淮安市| 石渠县| 和平区| 武平县| 离岛区| 马公市| 东乌珠穆沁旗| 上高县| 金塔县| 磐安县| 景德镇市| 施秉县| 夏邑县| 禹城市| 崇仁县| 清水县| 潼关县| 三原县| 嵊州市| 平利县| 扶绥县| 扶绥县| 湖口县| 喀什市| 共和县| 南雄市| 宁波市|