Java爬虫Get校花网所有美女图片,附源代码


点击上方“ java工会 ”,选择“置顶公众号”
关键时刻,第一时间送达!

640?wx_fmt=gif


阅读本文需要5分钟,加群获取源代码

前言

作为一个宅男,每天看看美女图是必修课。那么——作为一个程序猿加宅男,如何收藏更多的美女图片呢?这就要用到爬虫了,哈哈,我仿佛看到了无穷无尽的美女在向我招手——怎么感觉写下这段话的时候自己略有一丝猥琐呢?啊呸,相当之猥琐!


我们的重点是学习写爬虫,嗯!


网络爬虫是做什么的?


他的主要工作就是 跟据指定的url地址 去发送请求,获得响应, 然后解析响应 , 一方面从响应中查找出想要查找的数据,另一方面从响应中解析出新的URL路径。


然后继续访问,继续解析;继续查找需要的数据和继续解析出新的URL路径


这就是网络爬虫主要干的工作.  下面是流程图:

640?wx_fmt=png


通过上面的流程图 能大概了解到 网络爬虫 干了哪些活  ,根据这些 也就能设计出一个简单的网络爬虫出来。


一个简单的爬虫 必需的功能: 

  1. 发送请求和获取响应的功能

  2. 解析响应的功能

  3. 过滤出的数据进行存储的功能

  4. 对解析出来的URL路径处理的功能


先看看运行效果

640?wx_fmt=png


下面是包结构


640?wx_fmt=png


核心代码


RequestAndResponseTool  类: 主要方法: 发送请求 返回响应 并把 响应 封装成 page 类

public class RequestAndResponseTool {


public static Page sendRequstAndGetResponse(String url) {
Page page = null;
       // 1.生成 HttpClinet 对象并设置参数
       HttpClient httpClient = new HttpClient();
       // 设置 HTTP 连接超时 5s
       httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
       // 2.生成 GetMethod 对象并设置参数
       GetMethod getMethod = new GetMethod(url);
       // 设置 get 请求超时 5s
       getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
       // 设置请求重试处理
       getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
       // 3.执行 HTTP GET 请求
       try {
int statusCode = httpClient.executeMethod(getMethod);
           // 判断访问的状态码
           if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + getMethod.getStatusLine());
           }
// 4.处理 HTTP 响应内容
           byte[] responseBody = getMethod.getResponseBody();// 读取为字节 数组
           String contentType = getMethod.getResponseHeader("Content-Type").getValue(); // 得到当前返回类型
           page = new Page(responseBody, url, contentType); //封装成为页面
       } catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
           System.out.println("Please check your provided http address!");
           e.printStackTrace();
       } catch (IOException e) {
// 发生网络异常
           e.printStackTrace();
       } finally {
// 释放连接
           getMethod.releaseConnection();
       }
return page;
   }
}


page 类: 主要作用: 保存响应的相关内容 对外提供访问方法

/*
* 保存获取到的响应的相关内容;
*/
public class Page {

private byte[] content;
   private String html;  //网页源码字符串
   private Document doc;//网页Dom文档
   private String charset;//字符编码
   private String url;//url路径
   private String contentType;// 内容类型


   public Page(byte[] content, String url, String contentType) {
this.content = content;
       this.url = url;
       this.contentType = contentType;
   }

public String getCharset() {
return charset;
   }

public String getUrl() {
return url;
   }

public String getContentType() {
return contentType;
   }

public byte[] getContent() {
return content;
   }

/**
    * 返回网页的源码字符串
    *
    * @return 网页的源码字符串
    */
   public String getHtml() {
if (html != null) {
return html;
       }
if (content == null) {
return null;
       }
if (charset == null) {
charset = CharsetDetector.guessEncoding(content); // 根据内容来猜测 字符编码
       }
try {
this.html = new String(content, charset);
           return html;
       } catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
           return null;
       }
}

/*
   *  得到文档
   * */
   public Document getDoc() {
if (doc != null) {
return doc;
       }
try {
this.doc = Jsoup.parse(getHtml(), url);
           return doc;
       } catch (Exception ex) {
ex.printStackTrace();
           return null;
       }
}


}


PageParserTool: 类  主要作用 提供了 根据选择器来选取元素 属性 等方法

public class PageParserTool {

/* 通过选择器来选取页面的 */
   public static Elements select(Page page, String cssSelector) {
return page.getDoc().select(cssSelector);
   }

/*
    *  通过css选择器来得到指定元素;
    *
    *  */
   public static Element select(Page page, String cssSelector, int index) {
Elements eles = select(page, cssSelector);
       int realIndex = index;
       if (index < 0) {
realIndex = eles.size() + index;
       }
return eles.get(realIndex);
   }

/**
    * 获取满足选择器的元素中的链接 选择器cssSelector必须定位到具体的超链接
    * 例如我们想抽取id为content的div中的所有超链接,这里
    * 就要将cssSelector定义为div[id=content] a
    * 放入set 中 防止重复;
    *
    * @param cssSelector
    * @return
    */
   public static Set<String> getLinks(Page page, String cssSelector) {
Set<String> links = new HashSet<String>();
       Elements es = select(page, cssSelector);
       Iterator iterator = es.iterator();
       while (iterator.hasNext()) {
Element element = (Element) iterator.next();
           if (element.hasAttr("href")) {
links.add(element.attr("abs:href"));
           } else if (element.hasAttr("src")) {
links.add(element.attr("abs:src"));
           }
}
return links;
   }

/**
    * 获取网页中满足指定css选择器的所有元素的指定属性的集合
    * 例如通过getAttrs("img[src]","abs:src")可获取网页中所有图片的链接
    *
    * @param cssSelector
    * @param attrName
    * @return
    */
   public static ArrayList<String> getAttrs(Page page, String cssSelector, String attrName) {
ArrayList<String> result = new ArrayList<String>();
       Elements eles = select(page, cssSelector);
       for (Element ele : eles) {
if (ele.hasAttr(attrName)) {
result.add(ele.attr(attrName));
           }
}
return result;
   }
}


Links  类:  两个属性: 一个是存放 已经访问的url集合的set  ; 一个是存放待访问url集合的 queue

/*
*  Link主要功能;
*  存储已经访问过的URL路径 和 待访问的URL 路径;
*/
public class Links {

//已访问的 url 集合  已经访问过的 主要考虑 不能再重复了 使用set来保证不重复;
   private static Set visitedUrlSet = new HashSet();

   //待访问的 url 集合  待访问的主要考虑 1:规定访问顺序;2:保证不提供重复的带访问地址;
   private static LinkedList unVisitedUrlQueue = new LinkedList();

   //获得已经访问的 URL 数目
   public static int getVisitedUrlNum() {
return visitedUrlSet.size();
   }

//添加到访问过的 URL
   public static void addVisitedUrlSet(String url) {
visitedUrlSet.add(url);
   }

//移除访问过的 URL
   public static void removeVisitedUrlSet(String url) {
visitedUrlSet.remove(url);
   }


//获得 待访问的 url 集合
   public static LinkedList getUnVisitedUrlQueue() {
return unVisitedUrlQueue;
   }

// 添加到待访问的集合中  保证每个 URL 只被访问一次
   public static void addUnvisitedUrlQueue(String url) {
if (url != null && !url.trim().equals("") && !visitedUrlSet.contains(url) && !unVisitedUrlQueue.contains(url)) {
unVisitedUrlQueue.add(url);
       }
}

//删除 待访问的url
   public static Object removeHeadOfUnVisitedUrlQueue() {
return unVisitedUrlQueue.removeFirst();
   }

//判断未访问的 URL 队列中是否为空
   public static boolean unVisitedUrlQueueIsEmpty() {
return unVisitedUrlQueue.isEmpty();
   }


}


LinkFilter  接口: 可以起过滤作用

public interface LinkFilter {
public boolean accept(String url);
}


获取源代码

1.加qq群727096055从群文件获取

2.加小编微信xili22xili备注代码获取


关注java工会,了解更多精彩

640?wx_fmt=jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值