java实现爬虫爬网站图片

第一步,实现 LinkQueue,对url进行过滤和存储的操作

[java] view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.Collections;  
  3. import java.util.HashSet;  
  4. import java.util.List;  
  5. import java.util.Set;  
  6.   
  7. public class LinkQueue {  
  8.   
  9.     // 已访问的 url 集合  
  10.     private static Set<String> visitedUrl = Collections.synchronizedSet(new HashSet<String>());  
  11.   
  12.     // 未访问的url  
  13.     private static List<String> unVisitedUrl = Collections.synchronizedList(new ArrayList<String>());  
  14.       
  15.     // 未访问的URL出队列  
  16.     public static String unVisitedUrlDeQueue() {  
  17.         if (unVisitedUrl.size() > 0) {  
  18.             String url = unVisitedUrl.remove(0);  
  19.             visitedUrl.add(url);  
  20.             return url;  
  21.         }  
  22.         return null;  
  23.     }  
  24.       
  25.       
  26.       
  27.     // 新的url添加进来的时候进行验证,保证只是添加一次  
  28.     public static void addUnvisitedUrl(String url) {  
  29.         if (url != null && !url.trim().equals("") && !visitedUrl.contains(url)  
  30.                 && !unVisitedUrl.contains(url))  
  31.             unVisitedUrl.add(url);  
  32.     }  
  33.       
  34.     // 判断未访问的URL队列中是否为空  
  35.     public static boolean unVisitedUrlsEmpty() {  
  36.         return unVisitedUrl.isEmpty();  
  37.     }  
  38.       
  39. }  

第二步,收集每一个url下的链接进行过滤产生新的链接
[java] view plain copy
  1. import java.util.HashSet;  
  2. import java.util.Set;  
  3. import org.htmlparser.Node;  
  4. import org.htmlparser.NodeFilter;  
  5. import org.htmlparser.Parser;  
  6. import org.htmlparser.filters.NodeClassFilter;  
  7. import org.htmlparser.filters.OrFilter;  
  8. import org.htmlparser.tags.LinkTag;  
  9. import org.htmlparser.util.NodeList;  
  10. import org.htmlparser.util.ParserException;  
  11.   
  12. /** 
  13.  * 过滤http的url,获取可以符合规则的url 
  14.  * @author Administrator 
  15.  * 
  16.  */  
  17. public class ParserHttpUrl {  
  18.       
  19.     // 获取一个网站上的链接,filter 用来过滤链接  
  20.     public static Set<String> extracLinks(String url, LinkFilter filter) {  
  21.         Set<String> links = new HashSet<String>();  
  22.         try {  
  23.             Parser parser = new Parser(url);  
  24.             // 过滤 <frame >标签的 filter,用来提取 frame 标签里的 src 属性所表示的链接  
  25.             NodeFilter frameFilter = new NodeFilter() {  
  26.                 public boolean accept(Node node) {  
  27.                     if (node.getText().startsWith("frame src=")) {  
  28.                         return true;  
  29.                     } else {  
  30.                         return false;  
  31.                     }  
  32.                 }  
  33.             };  
  34.             // OrFilter 来设置过滤 <a> 标签,和 <frame> 标签  
  35.             OrFilter linkFilter = new OrFilter(new NodeClassFilter(  
  36.                     LinkTag.class), frameFilter);  
  37.             // 得到所有经过过滤的标签  
  38.             NodeList list = parser.extractAllNodesThatMatch(linkFilter);  
  39.             for (int i = 0; i < list.size(); i++) {  
  40.                 Node tag = list.elementAt(i);  
  41.                 if (tag instanceof LinkTag)// <a> 标签  
  42.                 {  
  43.                     LinkTag link = (LinkTag) tag;  
  44.                     String linkUrl = link.getLink();// url  
  45.                     if (filter.accept(linkUrl))  
  46.                         links.add(linkUrl);  
  47.                 } else// <frame> 标签  
  48.                 {  
  49.                     // 提取 frame 里 src 属性的链接如 <frame src="test.html"/>  
  50.                     String frame = tag.getText();  
  51.                     int start = frame.indexOf("src=");  
  52.                     frame = frame.substring(start);  
  53.                     int end = frame.indexOf(" ");  
  54.                     if (end == -1)  
  55.                         end = frame.indexOf(">");  
  56.                     String frameUrl = frame.substring(5, end - 1);  
  57.                     if (filter.accept(frameUrl))  
  58.                         links.add(frameUrl);  
  59.                 }  
  60.             }  
  61.         } catch (ParserException e) {  
  62.             e.printStackTrace();  
  63.         }  
  64.         return links;  
  65.     }  
  66. }  

第三步,实现图片下载功能  
[java] view plain copy
  1. import java.io.File;  
  2. import java.io.FileOutputStream;  
  3. import java.io.InputStream;  
  4. import java.net.URL;  
  5. import java.net.URLConnection;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8. import java.util.regex.Matcher;  
  9. import java.util.regex.Pattern;  
  10.   
  11. /*** 
  12.  * java抓取网络图片 
  13.  *  
  14.  * @author swinglife 
  15.  *  
  16.  */  
  17. public class DownLoadPic {  
  18.   
  19.     // 编码  
  20.     private static final String ECODING = "UTF-8";  
  21.     // 获取img标签正则  
  22.     private static final String IMGURL_REG = "<img.*src=(.*?)[^>]*?>";  
  23.     // 获取src路径的正则  
  24.     private static final String IMGSRC_REG = "http:\"?(.*?)(\"|>|\\s+)";  
  25.   
  26.     public static void downloadPic(String url) {  
  27.         // 获得html文本内容  
  28.         String HTML = null;  
  29.         try {  
  30.             HTML = DownLoadPic.getHTML(url);  
  31.         } catch (Exception e) {  
  32.             e.printStackTrace();  
  33.         }  
  34.         if (null != HTML && !"".equals(HTML)) {  
  35.   
  36.             // 获取图片标签  
  37.             List<String> imgUrl = DownLoadPic.getImageUrl(HTML);  
  38.             // 获取图片src地址  
  39.             List<String> imgSrc = DownLoadPic.getImageSrc(imgUrl);  
  40.             // 下载图片  
  41.             DownLoadPic.download(imgSrc);  
  42.         }  
  43.     }  
  44.   
  45.     /*** 
  46.      * 获取HTML内容 
  47.      *  
  48.      * @param url 
  49.      * @return 
  50.      * @throws Exception 
  51.      */  
  52.     private static String getHTML(String url) throws Exception {  
  53.         URL uri = new URL(url);  
  54.         URLConnection connection = uri.openConnection();  
  55.         InputStream in = connection.getInputStream();  
  56.         byte[] buf = new byte[1024];  
  57.         int length = 0;  
  58.         StringBuffer sb = new StringBuffer();  
  59.         while ((length = in.read(buf, 0, buf.length)) > 0) {  
  60.             sb.append(new String(buf, ECODING));  
  61.         }  
  62.         in.close();  
  63.         return sb.toString();  
  64.     }  
  65.   
  66.     /*** 
  67.      * 获取ImageUrl地址 
  68.      *  
  69.      * @param HTML 
  70.      * @return 
  71.      */  
  72.     private static List<String> getImageUrl(String HTML) {  
  73.         Matcher matcher = Pattern.compile(IMGURL_REG).matcher(HTML);  
  74.         List<String> listImgUrl = new ArrayList<String>();  
  75.         while (matcher.find()) {  
  76.             listImgUrl.add(matcher.group());  
  77.         }  
  78.         return listImgUrl;  
  79.     }  
  80.   
  81.     /*** 
  82.      * 获取ImageSrc地址 
  83.      *  
  84.      * @param listImageUrl 
  85.      * @return 
  86.      */  
  87.     private static List<String> getImageSrc(List<String> listImageUrl) {  
  88.         List<String> listImgSrc = new ArrayList<String>();  
  89.         for (String image : listImageUrl) {  
  90.             Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);  
  91.             while (matcher.find()) {  
  92.                 listImgSrc.add(matcher.group().substring(0,  
  93.                         matcher.group().length() - 1));  
  94.             }  
  95.         }  
  96.         return listImgSrc;  
  97.     }  
  98.   
  99.     /*** 
  100.      * 下载图片 
  101.      *  
  102.      * @param listImgSrc 
  103.      */  
  104.     private static void download(List<String> listImgSrc) {  
  105.   
  106.         for (String url : listImgSrc) {  
  107.             try {  
  108.                 String imageName = url.substring(url.lastIndexOf("/") + 1,  
  109.                         url.length());  
  110.                   
  111.                 URL uri = new URL(url);  
  112.                 InputStream in = uri.openStream();  
  113.                 FileOutputStream fo = new FileOutputStream(new File(imageName));  
  114.                 byte[] buf = new byte[1024];  
  115.                 int length = 0;  
  116.                 while ((length = in.read(buf, 0, buf.length)) != -1) {  
  117.                     fo.write(buf, 0, length);  
  118.                 }  
  119.                 in.close();  
  120.                 fo.close();  
  121.             } catch (Exception e) {  
  122.                 e.printStackTrace();  
  123.             }  
  124.         }  
  125.     }  
  126.   
  127. }  

实在Filter接口,定义过滤接口:
[java] view plain copy
  1. public interface Filter {  
  2.   
  3.     public boolean accept(String url);  
  4. }  
第四步,过滤规则的实现:
[java] view plain copy
  1. public class Crawler {  
  2.   
  3.     /** 
  4.      * 抓取过程 
  5.      *  
  6.      * @return 
  7.      * @param seeds 
  8.      */  
  9.     public void crawling(String url) { // 定义过滤器  
  10.           
  11.         Filter filter = new Filter() {  
  12.             public boolean accept(String url) {  
  13.                 //这里过滤规则随需要爬的网站的规则进行改变,推荐使用正则实现,本人是爬豆瓣网站  
  14.                 if(url.indexOf("douban.com/group/topic") != -1 || url.indexOf("douban.com/group/haixiuzu/discussion?start") != -1 )  
  15.                     return true;  
  16.                 else  
  17.                     return false;  
  18.             }  
  19.         };  
  20.         // 初始化 URL 队列  
  21.         LinkQueue.addUnvisitedUrl(url);  
  22.           
  23.         // 循环条件,待抓取的链接不空  
  24.         while (!LinkQueue.unVisitedUrlsEmpty()) {  
  25.             // 队头URL出队列  
  26.             String visitUrl = (String) LinkQueue.unVisitedUrlDeQueue();  
  27.             if (visitUrl == null)  
  28.                 continue;  
  29.               
  30.             DownLoadPic.downloadPic(visitUrl);  
  31.   
  32.             // 提取出下载网页中的 URL  
  33.             Set<String> links = ParserHttpUrl.extracLinks(visitUrl, filter);  
  34.             // 新的未访问的 URL 入队  
  35.             for (String link : links) {  
  36.                 LinkQueue.addUnvisitedUrl(link);  
  37.             }  
  38.         }  
  39.     }  
  40.   
  41.     // main 方法入口  
  42.     public static void main(String[] args) {  
  43.         Crawler crawler = new Crawler();  
  44.         crawler.crawling("http://www.douban.com/group/haixiuzu/discussion?start=0");  
  45.     }  

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值