1. package com.test.pic.crawler;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.net.URL;
  9. import java.net.URLConnection;
  10. import java.util.Arrays;
  11. import java.util.HashSet;
  12. import java.util.List;
  13. import java.util.Set;
  14. import java.util.concurrent.BlockingQueue;
  15. import java.util.concurrent.LinkedBlockingDeque;
  16. import java.util.concurrent.ScheduledExecutorService;
  17. import java.util.concurrent.ScheduledThreadPoolExecutor;
  18. import org.apache.commons.lang3.concurrent.BasicThreadFactory;
  19. import org.jsoup.Jsoup;
  20. import org.jsoup.nodes.*;
  21. import org.jsoup.select.Elements;
  22.  
  23. /**
  24. * @Title: PicCrawler.java
  25. *
  26. * @Package com.test.pic.crawler
  27. *
  28. * @Description: 爬取指定网站的指定Tag下的图片或者全部Tag图片
  29. *
  30. * @author CoderZZ
  31. *
  32. * @date 2018年1月12日 下午11:22:41
  33. *
  34. * @version V1.0
  35. *
  36. */
  37. public class PicCrawler implements Runnable{
  38. private static String pathString = "G:/test/pic/";//存储目录
  39. //存储真正的爬取页面
  40. static BlockingQueue<String> urlBlockingQueue = new LinkedBlockingDeque<String>(1000);
  41. static int threadNum = 10;
  42. // public PicCrawler(String url){
  43. // this.url = url;
  44. // }
  45.  
  46. /**
  47. * @Title: main
  48. *
  49. * @Description: TODO(这里用一句话描述这个方法的作用)
  50. *
  51. * @param @param args 设定文件
  52. *
  53. * @return void 返回类型
  54. *
  55. * @throws
  56. *
  57. */
  58. public static void main(String[] args) {
  59. String homeurlString = "https://www.xxxx.com";//爬取页面的基本地址
  60. String tagPageUrl = "https://www.xxxx.com/tag/";//tag分页地址
  61. //Tag标签的完整路径
  62. Set<String> tagFullHrefSet = new HashSet<String>(16);
  63. //想要爬取哪些tag,如果为空,则全部爬取;否则只配置对应的tag
  64. String[] crawlerTagArray = {"风景"};
  65. List<String> crawlerTagList = Arrays.asList(crawlerTagArray);
  66. try {
  67. //1.获取想要的tag完整的url
  68. Document tagListDocument = Jsoup.connect(tagPageUrl).get();
  69. Elements tagsListDivElements = tagListDocument.getElementsByClass("tags_list");
  70. for(Element element:tagsListDivElements){
  71. Elements aElements = element.getElementsByTag("a");
  72. for(Element a:aElements){
  73. if(crawlerTagList.size() == 0 || crawlerTagList.contains(a.text())){
  74. String tagUrlString = homeurlString+a.attr("href");
  75. //https://www.xxxx.com/tag/fengjing.html
  76. tagUrlString = tagUrlString.substring(0, tagUrlString.lastIndexOf("."))+"/1.html";
  77. tagFullHrefSet.add(tagUrlString);
  78. }
  79. }
  80. }
  81. //2.获取图片链接页面地址,分页爬取
  82. for(String tagUrl:tagFullHrefSet){
  83. String tempTagUrlString = tagUrl;
  84. int currentPageNum = 1;
  85. while(true){
  86. try{
  87. Document imagePageDocument = Jsoup.connect(tempTagUrlString).get();
  88. Elements imageListElements = imagePageDocument.getElementsByClass("Pli-litpic");
  89. if(imageListElements.size() == 0){
  90. break;
  91. }
  92. for(Element image:imageListElements){
  93. urlBlockingQueue.offer(homeurlString+image.attr("href"));
  94. }
  95. //https://www.xxxx.com/tag/fengjing/1.html
  96. tempTagUrlString = tempTagUrlString.substring(0, tempTagUrlString.lastIndexOf("/")+1)+(++currentPageNum)+".html";
  97. }catch(Exception e){
  98. break;
  99. }
  100. }
  101. }
  102. ScheduledExecutorService excutor = new ScheduledThreadPoolExecutor(threadNum,new BasicThreadFactory.Builder().namingPattern("my-crawler-thread-%d").daemon(false).build());
  103. for(int i=0;i<threadNum;i++){
  104. // excutor.schedule(new PicCrawler(urlArray[i]), 1, TimeUnit.SECONDS);
  105. // excutor.execute(new PicCrawler(urlArray[i]));
  106. excutor.submit(new PicCrawler());
  107. }
  108. } catch (IOException e) {
  109. // TODO Auto-generated catch block
  110. e.printStackTrace();
  111. }
  112. }
  113. @Override
  114. public void run() {
  115. while (true) {
  116. try {
  117. long begin = System.currentTimeMillis();
  118. String url = urlBlockingQueue.poll();
  119. if(null != url){
  120. Document doc = Jsoup.connect(url).get();
  121. Elements titleElements =doc.select("#photos > h1");
  122. if(null != titleElements && null != titleElements.get(0)){
  123. Set<String> imgSrcSet = new HashSet<String>(16);
  124. Element titleElement = titleElements.get(0);
  125. String foldNameString = titleElement.text();
  126. String[] nameArray = foldNameString.split("\\(");
  127. foldNameString = nameArray[0];
  128. nameArray = nameArray[1].split("/");
  129. int totalPaggs = Integer.parseInt(nameArray[1].replace(")", ""));
  130. for(int i=1;i<=totalPaggs;i++){
  131. String urlTemp = url.replace(".html", "_"+i+".html");
  132. Document docTemp = Jsoup.connect(urlTemp).get();
  133. Element element = docTemp.getElementById("big-pic");
  134. Elements imgElements = element.getElementsByTag("img");
  135. for(Element imgElement:imgElements){
  136. imgSrcSet.add(imgElement.attr("src"));
  137. }
  138. }
  139. if(imgSrcSet.size()>0){
  140. for(String imgSrc:imgSrcSet){
  141. // 构造URL
  142. URL imgurl = new URL(imgSrc);
  143. // 打开连接
  144. URLConnection con = imgurl.openConnection();
  145. //设置请求超时为10s
  146. con.setConnectTimeout(10*1000);
  147. // 输入流
  148. InputStream is = con.getInputStream();
  149. // 500k的数据缓冲
  150. byte[] bs = new byte[1024*500];
  151. // 读取到的数据长度
  152. int len;
  153. // 输出的文件流
  154. File sf=new File(pathString+"\\"+foldNameString);
  155. if(!sf.exists()){
  156. sf.mkdirs();
  157. }
  158. String filename = imgSrc.split("/")[imgSrc.split("/").length-1];
  159. OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);
  160. // 开始读取
  161. while ((len = is.read(bs)) != -1) {
  162. os.write(bs, 0, len);
  163. }
  164. // 完毕,关闭所有链接
  165. os.close();
  166. is.close();
  167. System.out.println(imgSrc+"下载完成!!!");
  168. }
  169. }
  170. long end = System.currentTimeMillis();
  171. System.out.println("================================================================");
  172. System.out.println(Thread.currentThread().getName()+"******************已全部下载完成,用时:"+((end-begin)/1000)+"S");
  173. }
  174. }else{
  175. System.out.println("========================BlockingQueue已空,已全部抓取完成!=======================");
  176. }
  177. } catch (Exception e) {
  178. System.out.println("========================抓取异常=======================");
  179. }
  180. }
  181. }
  182. }

使用Jsoup爬取网站图片的更多相关文章

  1. jsoup爬取网站图片

    package com.ij34.JsoupTest; import java.io.File; import java.io.FileOutputStream; import java.io.Inp ...

  2. Python:爬取网站图片并保存至本地

    Python:爬取网页图片并保存至本地 python3爬取网页中的图片到本地的过程如下: 1.爬取网页 2.获取图片地址 3.爬取图片内容并保存到本地 实例:爬取百度贴吧首页图片. 代码如下: imp ...

  3. Day11 (黑客成长日记) 爬取网站图片

    #导入第三方库# coding:utf-8import requests,re #找到需要爬取的网站'http://www.qqjia.com/sucai/sucai1210.htm' #1>获 ...

  4. webmagic 二次开发爬虫 爬取网站图片

    webmagic的是一个无须配置.便于二次开发的爬虫框架,它提供简单灵活的API,只需少量代码即可实现一个爬虫. webmagic介绍 编写一个简单的爬虫 webmagic的使用文档:http://w ...

  5. 使用ajax爬取网站图片()

    以下内容转载自:https://www.makcyun.top/web_scraping_withpython4.html 文章关于网站使用Ajaxj技术加载页面数据,进行爬取讲的很详细 大致步骤如下 ...

  6. 【Python】爬取网站图片

    import requests import bs4 import urllib.request import urllib import os hdr = {'User-Agent': 'Mozil ...

  7. Jsoup爬取带登录验证码的网站

    今天学完爬虫之后想的爬一下我们学校的教务系统,可是发现登录的时候有验证码.因此研究了Jsoup爬取带验证码的网站: 大体的思路是:(需要注意的是__VIEWSTATE一直变化,所以我们每个页面都需要重 ...

  8. jsoup爬取某网站安全数据

    jsoup爬取某网站安全数据 package com.vfsd.net; import java.io.IOException; import java.sql.SQLException; impor ...

  9. Python爬虫学习(6): 爬取MM图片

    为了有趣我们今天就主要去爬取以下MM的图片,并将其按名保存在本地.要爬取的网站为: 大秀台模特网 1. 分析网站 进入官网后我们发现有很多分类: 而我们要爬取的模特中的女模内容,点进入之后其网址为:h ...

随机推荐

  1. 石川es6课程---12、Promise

    石川es6课程---12.Promise 一.总结 一句话总结: 用同步的方式来书写异步代码,让异步书写变的特别简单 用同步的方式来书写异步代码Promise 让异步操作写起来,像在写同步操作的流程, ...

  2. STL priority_queue

    priority_queue 优先队列(Priority Queues):顾名思义,一个有着优先级的队列.它是一种ADT,和队列的思想差不多—— 排队,数据结构中的队列是不能插队的,不能颠倒排队的顺序 ...

  3. LC 609. Find Duplicate File in System

    Given a list of directory info including directory path, and all the files with contents in this dir ...

  4. vue 默认展开详情页

    { path: '/Tree', component: Tree, children: [ { path: '/', component: Come } ] }

  5. AutoCompleteTextView实现搜索提示功能的实现

    AutoCompleteTextView和EditText组件类似,都可以输入文本.但AutoCompleteTextView组件可以和一个字符串数组或List对象绑定,当用户输入两个及以上字符时,系 ...

  6. 惠州双月湾游记 & 攻略

    惠州双月湾游记&攻略 2019 年的 11 月底和小朱.Josie 约了快乐周末去惠州双月湾玩! 我和时猪一起从武汉出发到广州,然后和他们俩一起从广州自驾去的惠州.大致行程如下: Day 1: ...

  7. linux常用、常见错误

    1.md5加密使用 oppnssl md5 加密字符串的方法 [root@lab3 ~]# openssl //在终端中输入openssl后回车. OpenSSL> md5 //输入md5后回车 ...

  8. 安卓渗透测试工具——Drozer(安装和使用)

    移动端渗透测试工具相比丰富的web端真的是少之又少,最近在做app的安全测试,用到了drozer,drozer的安装过程真的是太心酸了,中间报错了有6次才成功安装.. 一.环境准备 首先准备以下环境: ...

  9. ASP.NET Core 入门笔记2,建立项目

    1.建立项目 2.项目结构 1.项目结构说明 根目录/文件 说明 .vscode目录 VS Code项目配置目录,相当于.vs..idea文件夹 bin目录 编译输出目录 obj目录 编译配置与中间目 ...

  10. 华为HCNA乱学Round 10:PPP&PAP