`
郑云飞
  • 浏览: 814017 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java广度优先爬虫示例

 
阅读更多
一.使用的技术
这个爬虫是近半个月前学习爬虫技术的一个小例子,比较简单,怕时间久了会忘,这里简单总结一下.主要用到的外部Jar包有HttpClient4.3.4,HtmlParser2.1,使用的开发工具(IDE)为intelij 13.1,Jar包管理工具为Maven,不习惯用intelij的同学,也可以使用eclipse新建一个项目.
 
二.爬虫基本知识
1.什么是网络爬虫?(爬虫的基本原理)
网络爬虫,拆开来讲,网络即指互联网,互联网就像一个蜘蛛网一样,爬虫就像是蜘蛛一样可以到处爬来爬去,把爬来的数据再进行加工处理.
 
百科上的解释:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。
 
基本原理:传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件,流程图所示。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止
 
 
 
2.常用的爬虫策略有哪些?
网页的抓取策略可以分为深度优先、广度优先和最佳优先三种。深度优先在很多情况下会导致爬虫的陷入(trapped)问题,目前常见的是广度优先和最佳优先方法。
 
2.1广度优先(Width-First)
 
广度优先遍历是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名.
 
其基本思想:
 
1)、从图中某个顶点V0出发,并访问此顶点;
2)、从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点;
3)、重复步骤2,直到全部顶点都被访问为止。
如下图所示:
 
 
 
 
 
2.2深度优先(Depth-First)
 
假设初始状态是图中所有顶点都未被访问,则深度优先搜索方法的步骤是:
1)选取图中某一顶点Vi为出发点,访问并标记该顶点;
2)以Vi为当前顶点,依次搜索Vi的每个邻接点Vj,若Vj未被访问过,则访问和标记邻接点Vj,若Vj已被访问过,则搜索Vi的下一个邻接点;
3)以Vj为当前顶点,重复步骤2,直到图中和Vi有路径相通的顶点都被访问为止;
4)若图中尚有顶点未被访问过(非连通的情况下),则可任取图中的一个未被访问的顶点作为出发点,重复上述过程,直至图中所有顶点都被访问。
下面以一个有向图和一个无向图为例:
 
 
 
 
 
 
 
 
 
广度和深度和区别:
 
广度优先遍历是以层为顺序,将某一层上的所有节点都搜索到了之后才向下一层搜索;而深度优先遍历是将某一条枝桠上的所有节点都搜索到了之后,才转向搜索另一条枝桠上的所有节点。
 
 
 
2.3 最佳优先搜索
 
最佳优先搜索策略按照一定的网页分析算法,预测候选URL与目标网页的相似度,或与主题的相关性,并选取评价最好的一个或几个URL进行抓取。它只访问经过网页分析算法预测为“有用”的网页。这种搜索适合暗网数据的爬取,只要符合要求的内容.
 
 
 
3.本文爬虫示例图
本文介绍的例子是抓取新闻类的信息,因为一般新闻类的信息,重要的和时间近的都会放在首页,处在网络层中比较深的信息的重要性一般将逐级降低,所以广度优先算法更适合,下图是本文将要抓取的网页结构图:
 
 
 
 
 
 
 
 
 
三.广度优先爬虫示例
1.需求:抓取复旦新闻信息(只抓取100个网页信息)
这里只抓取100条信息,并用url必须以new.fudan.edu.cn开头.
 
2.代码实现
使用maven引入外部jar包:
 
复制代码
       <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.htmlparser</groupId>
            <artifactId>htmlparser</artifactId>
            <version>2.1</version>
        </dependency>        
复制代码
 
 
程序主入口:
 
复制代码
package com.amos.crawl;
 
import java.util.Set;
 
/**
 * Created by amosli on 14-7-10.
 */
public class MyCrawler {
    /**
     * 使用种子初始化URL队列
     *
     * @param seeds
     */
    private void initCrawlerWithSeeds(String[] seeds) {
        for (int i = 0; i < seeds.length; i++) {
            LinkQueue.addUnvisitedUrl(seeds[i]);
        }
    }
 
    public void crawling(String[] seeds) {
        //定义过滤器,提取以http://news.fudan.edu.cn/的链接
        LinkFilter filter = new LinkFilter() {
            @Override
            public boolean accept(String url) {
                if (url.startsWith("http://news.fudan.edu.cn")) {
                    return true;
                }
                return false;
            }
        };
        //初始化URL队列
        initCrawlerWithSeeds(seeds);
 
        int count=0;
        //循环条件:待抓取的链接不为空抓取的网页最多100条
        while (!LinkQueue.isUnvisitedUrlsEmpty() && LinkQueue.getVisitedUrlNum() <= 100) {
 
            System.out.println("count:"+(++count));
 
            //附头URL出队列
            String visitURL = (String) LinkQueue.unVisitedUrlDeQueue();
            DownLoadFile downloader = new DownLoadFile();
            //下载网页
            downloader.downloadFile(visitURL);
            //该URL放入怩访问的URL中
            LinkQueue.addVisitedUrl(visitURL);
            //提取出下载网页中的URL
            Set<String> links = HtmlParserTool.extractLinks(visitURL, filter);
 
            //新的未访问的URL入列
            for (String link : links) {
                System.out.println("link:"+link);
                LinkQueue.addUnvisitedUrl(link);
            }
        }
 
    }
 
    public static void main(String args[]) {
        //程序入口
        MyCrawler myCrawler = new MyCrawler();
        myCrawler.crawling(new String[]{"http://news.fudan.edu.cn/news/"});
    }
 
}
 
复制代码
package com.amos.tool;
 
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Locale;
 
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
 
import org.apache.http.*;
import org.apache.http.client.CircularRedirectException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Args;
import org.apache.http.util.Asserts;
import org.apache.http.util.TextUtils;
import org.omg.CORBA.Request;
 
/**
 * Created by amosli on 14-6-25.
 */
public class Tools {
 
 
    /**
     * 写文件到本地
     *
     * @param httpEntity
     * @param filename
     */
    public static void saveToLocal(HttpEntity httpEntity, String filename) {
 
        try {
 
            File dir = new File(Configuration.FILEDIR);
            if (!dir.isDirectory()) {
                dir.mkdir();
            }
 
            File file = new File(dir.getAbsolutePath() + "/" + filename);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            InputStream inputStream = httpEntity.getContent();
 
            byte[] bytes = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(bytes)) > 0) {
                fileOutputStream.write(bytes, 0, length);
            }
            inputStream.close();
            fileOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    /**
     * 写文件到本地
     *
     * @param bytes
     * @param filename
     */
    public static void saveToLocalByBytes(byte[] bytes, String filename) {
 
        try {
 
            File dir = new File(Configuration.FILEDIR);
            if (!dir.isDirectory()) {
                dir.mkdir();
            }
 
            File file = new File(dir.getAbsolutePath() + "/" + filename);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(bytes);
                //fileOutputStream.write(bytes, 0, bytes.length);
                fileOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    /**
     * 输出
     * @param string
     */
    public static void println(String string){
        System.out.println("string:"+string);
    }
    /**
     * 输出
     * @param string
     */
    public static void printlnerr(String string){
        System.err.println("string:"+string);
    }
 
 
    /**
     * 使用ssl通道并设置请求重试处理
     * @return
     */
    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                public boolean isTrusted(X509Certificate[] chain,String authType) throws CertificateException {
                    return true;
                }
            }).build();
 
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
 
            //设置请求重试处理,重试机制,这里如果请求失败会重试5次
            HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
                @Override
                public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                    if (executionCount >= 5) {
                        // Do not retry if over max retry count
                        return false;
                    }
                    if (exception instanceof InterruptedIOException) {
                        // Timeout
                        return false;
                    }
                    if (exception instanceof UnknownHostException) {
                        // Unknown host
                        return false;
                    }
                    if (exception instanceof ConnectTimeoutException) {
                        // Connection refused
                        return false;
                    }
                    if (exception instanceof SSLException) {
                        // SSL handshake exception
                        return false;
                    }
                    HttpClientContext clientContext = HttpClientContext.adapt(context);
                    HttpRequest request = clientContext.getRequest();
                    boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                    if (idempotent) {
                        // Retry if the request is considered idempotent
                        return true;
                    }
                    return false;
                }
            };
 
            //请求参数设置,设置请求超时时间为20秒,连接超时为10秒,不允许循环重定向
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(20000).setConnectTimeout(20000)
                    .setCircularRedirectsAllowed(false)
                    .build();
 
            Cookie cookie ;
            return HttpClients.custom().setSSLSocketFactory(sslsf)
                    .setUserAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36")
                    .setMaxConnPerRoute(25).setMaxConnPerRoute(256)
                    .setRetryHandler(retryHandler)
                    .setRedirectStrategy(new SelfRedirectStrategy())
                    .setDefaultRequestConfig(requestConfig)
                    .build();
 
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }
 
    /**
     * 带cookiestore
     * @param cookieStore
     * @return
     */
 
    public static CloseableHttpClient createSSLClientDefaultWithCookie(CookieStore cookieStore) {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                public boolean isTrusted(X509Certificate[] chain,String authType) throws CertificateException {
                    return true;
                }
            }).build();
 
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
 
            //设置请求重试处理,重试机制,这里如果请求失败会重试5次
            HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
                @Override
                public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                    if (executionCount >= 5) {
                        // Do not retry if over max retry count
                        return false;
                    }
                    if (exception instanceof InterruptedIOException) {
                        // Timeout
                        return false;
                    }
                    if (exception instanceof UnknownHostException) {
                        // Unknown host
                        return false;
                    }
                    if (exception instanceof ConnectTimeoutException) {
                        // Connection refused
                        return false;
                    }
                    if (exception instanceof SSLException) {
                        // SSL handshake exception
                        return false;
                    }
                    HttpClientContext clientContext = HttpClientContext.adapt(context);
                    HttpRequest request = clientContext.getRequest();
                    boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                    if (idempotent) {
                        // Retry if the request is considered idempotent
                        return true;
                    }
                    return false;
                }
            };
 
            //请求参数设置,设置请求超时时间为20秒,连接超时为10秒,不允许循环重定向
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(20000).setConnectTimeout(20000)
                    .setCircularRedirectsAllowed(false)
                    .build();
 
 
            return HttpClients.custom().setSSLSocketFactory(sslsf)
                    .setUserAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36")
                    .setMaxConnPerRoute(25).setMaxConnPerRoute(256)
                    .setRetryHandler(retryHandler)
                    .setRedirectStrategy(new SelfRedirectStrategy())
                    .setDefaultRequestConfig(requestConfig)
                    .setDefaultCookieStore(cookieStore)
                    .build();
 
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }
 
}
复制代码
 
 
将网页写入到本地的下载类:DownLoadFile.java
 
 
复制代码
package com.amos.crawl;
 
import com.amos.tool.Configuration;
import com.amos.tool.Tools;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.AutoRetryHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HttpContext;
 
import javax.net.ssl.SSLException;
import java.io.*;
import java.net.UnknownHostException;
 
 
/**
 * Created by amosli on 14-7-9.
 */
public class DownLoadFile {
 
    public String getFileNameByUrl(String url, String contentType) {
        //移除http http://
        url = url.contains("http://") ? url.substring(7) : url.substring(8);
 
        //text/html类型
        if (url.contains(".html")) {
            url = url.replaceAll("[\\?/:*|<>\"]", "_");
        } else if (contentType.indexOf("html") != -1) {
            url = url.replaceAll("[\\?/:*|<>\"]", "_") + ".html";
        } else {
            url = url.replaceAll("[\\?/:*|<>\"]", "_") + "." + contentType.substring(contentType.lastIndexOf("/") + 1);
        }
        return url;
    }
 
    /**
     * 将网页写入到本地
     * @param data
     * @param filePath
     */
    private void saveToLocal(byte[] data, String filePath) {
 
        try {
            DataOutputStream out = new DataOutputStream(new FileOutputStream(new File(filePath)));
            for(int i=0;i<data.length;i++){
                out.write(data[i]);
            }
            out.flush();
            out.close();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 写文件到本地
     *
     * @param httpEntity
     * @param filename
     */
    public static void saveToLocal(HttpEntity httpEntity, String filename) {
 
        try {
 
            File dir = new File(Configuration.FILEDIR);
            if (!dir.isDirectory()) {
                dir.mkdir();
            }
 
            File file = new File(dir.getAbsolutePath() + "/" + filename);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            InputStream inputStream = httpEntity.getContent();
 
            if (!file.exists()) {
                file.createNewFile();
            }
            byte[] bytes = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(bytes)) > 0) {
                fileOutputStream.write(bytes, 0, length);
            }
            inputStream.close();
            fileOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
 
    public String downloadFile(String url)  {
 
        //文件路径
        String filePath=null;
 
        //1.生成HttpClient对象并设置参数
        HttpClient httpClient = Tools.createSSLClientDefault();
 
        //2.HttpGet对象并设置参数
        HttpGet httpGet = new HttpGet(url);
 
        //设置get请求超时5s
        //方法1
        //httpGet.getParams().setParameter("connectTimeout",5000);
        //方法2
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).build();
        httpGet.setConfig(requestConfig);
 
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if(statusCode!= HttpStatus.SC_OK){
                System.err.println("Method failed:"+httpResponse.getStatusLine());
                filePath=null;
            }
 
            filePath=getFileNameByUrl(url,httpResponse.getEntity().getContentType().getValue());
            saveToLocal(httpResponse.getEntity(),filePath);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return filePath;
 
    }
 
 
 
    public static void main(String args[]) throws IOException {
        String url = "http://websearch.fudan.edu.cn/search_dep.html";
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse httpResponse = httpClient.execute(httpGet);
        Header contentType = httpResponse.getEntity().getContentType();
 
        System.out.println("name:" + contentType.getName() + "value:" + contentType.getValue());
        System.out.println(new DownLoadFile().getFileNameByUrl(url, contentType.getValue()));
 
    }
 
 
}
复制代码
创建一个过滤接口:LinkFilter.java
 
复制代码
package com.amos.crawl;
 
/**
 * Created by amosli on 14-7-10.
 */
public interface LinkFilter {
 
    public boolean accept(String url);
 
}
复制代码
 
 
使用HtmlParser的过滤url的方法:HtmlParserTool.java
 
复制代码
package com.amos.crawl;
 
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
 
import java.util.HashSet;
import java.util.Set;
 
/**
 * Created by amosli on 14-7-10.
 */
public class HtmlParserTool {
    public static Set<String> extractLinks(String url, LinkFilter filter) {
        Set<String> links = new HashSet<String>();
 
        try {
            Parser parser = new Parser(url);
            parser.setEncoding("GBK");
            //过滤<frame>标签的filter,用来提取frame标签里的src属性
            NodeFilter framFilter = new NodeFilter() {
                @Override
                public boolean accept(Node node) {
                    if (node.getText().contains("frame src=")) {
                        return true;
                    } else {
                        return false;
                    }
 
                }
            };
 
            //OrFilter来设置过滤<a>标签和<frame>标签
            OrFilter linkFilter = new OrFilter(new NodeClassFilter(LinkTag.class), framFilter);
            //得到所有经过过滤的标签
            NodeList list = parser.extractAllNodesThatMatch(linkFilter);
            for (int i = 0; i < list.size(); i++) {
                Node tag = list.elementAt(i);
                if (tag instanceof LinkTag) {
                    tag = (LinkTag) tag;
                    String linkURL = ((LinkTag) tag).getLink();
 
                    //如果符合条件那么将url添加进去
                    if (filter.accept(linkURL)) {
                        links.add(linkURL);
                    }
 
                } else {//frame 标签
                    //frmae里src属性的链接,如<frame src="test.html" />
                    String frame = tag.getText();
                    int start = frame.indexOf("src=");
                    frame = frame.substring(start);
 
                    int end = frame.indexOf(" ");
                    if (end == -1) {
                        end = frame.indexOf(">");
                    }
                    String frameUrl = frame.substring(5, end - 1);
                    if (filter.accept(frameUrl)) {
                        links.add(frameUrl);
                    }
                }
 
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return links;
    }
 
 
}
复制代码
 
 
 
管理网页url的实现队列: Queue.java
 
复制代码
package com.amos.crawl;
 
import java.util.LinkedList;
 
/**
 * Created by amosli on 14-7-9.
 */
public class Queue {
 
    //使用链表实现队列
    private LinkedList queueList = new LinkedList();
 
 
    //入队列
    public void enQueue(Object object) {
        queueList.addLast(object);
    }
 
    //出队列
    public Object deQueue() {
        return queueList.removeFirst();
    }
 
    //判断队列是否为空
    public boolean isQueueEmpty() {
        return queueList.isEmpty();
    }
 
    //判断队列是否包含ject元素..
    public boolean contains(Object object) {
        return queueList.contains(object);
    }
 
    //判断队列是否为空
    public boolean empty() {
        return queueList.isEmpty();
    }
 
}
 
复制代码
 
 
网页链接进出队列的管理:LinkQueue.java
 
复制代码
package com.amos.crawl;
 
import java.util.HashSet;
import java.util.Set;
 
/**
 * Created by amosli on 14-7-9.
 */
public class LinkQueue {
    //已经访问的队列
    private static Set visitedUrl = new HashSet();
    //未访问的队列
    private static Queue unVisitedUrl = new Queue();
 
    //获得URL队列
    public static Queue getUnVisitedUrl() {
        return unVisitedUrl;
    }
    public static Set getVisitedUrl() {
        return visitedUrl;
    }
    //添加到访问过的URL队列中
    public static void addVisitedUrl(String url) {
        visitedUrl.add(url);
    }
 
    //删除已经访问过的URL
    public static void removeVisitedUrl(String url){
        visitedUrl.remove(url);
    }
    //未访问的URL出队列
    public static Object unVisitedUrlDeQueue(){
        return unVisitedUrl.deQueue();
    }
    //保证每个URL只被访问一次,url不能为空,同时已经访问的URL队列中不能包含该url,而且因为已经出队列了所未访问的URL队列中也不能包含该url
    public static void addUnvisitedUrl(String url){
        if(url!=null&&!url.trim().equals("")&&!visitedUrl.contains(url)&&!unVisitedUrl.contains(url))
        unVisitedUrl.enQueue(url);
    }
    //获得已经访问过的URL的数量
    public static int getVisitedUrlNum(){
        return visitedUrl.size();
    }
 
    //判断未访问的URL队列中是否为空
    public static boolean isUnvisitedUrlsEmpty(){
        return unVisitedUrl.empty();
    }
}
复制代码
 
 
抓取思路是:首先给出要抓取的url==>查询符合条件的url,并将其加入到队列中==>按顺序取出队列中的url,并访问之,同时取出符合条件的url==>下载队列中的url网页,即按层探索,最多限制100条数据.
 
分享到:
评论

相关推荐

    java实现的爬虫,亲自编写,测试通过

    Java实现的爬虫是软件开发领域中一个常见且实用的技术,尤其在大数据处理、数据分析以及信息获取方面。在这个项目中,"java实现的爬虫1号"是一个已经编写完成并经过测试验证的爬虫程序,它能直接导入到Java工程中...

    JAVA基于网络爬虫的搜索引擎设计与实现.pdf

    * 爬取策略包括广度优先爬取、深度优先爬取等,用于控制爬虫的爬取过程。 * 数据解析算法包括HTML解析、XML解析等,用于处理爬取的数据。 七、结论 * 本文档提出了一个基于Java的网络爬虫搜索引擎的设计和实现,...

    zhizhu.rar_java 爬虫_java实现爬虫_爬虫 java_爬虫网站

    本项目“zhizhu.rar”显然提供了一个用Java编写的爬虫示例,帮助用户了解如何利用Java实现爬虫功能,从而采集一般网站的数据。 首先,Java作为一种面向对象的编程语言,因其跨平台性和丰富的库支持,成为了开发爬虫...

    java深度优先遍历

    深度优先遍历(Depth First Search,DFS)是图论与数据结构中的一种经典搜索算法,主要应用于树或图的遍历。在Java中,我们可以利用递归或栈数据结构来实现这一算法。DFS的主要思想是从根节点开始,沿着某一条路径...

    Java网络爬虫(蜘蛛)源码

    爬虫还会遵循网页上的链接,递归地抓取整个网站或特定部分,这个过程称为深度优先搜索或广度优先搜索。 在Java中,我们可以使用以下库来实现网络爬虫: 1. Jsoup:这是一个非常流行的库,用于解析HTML和提取结构化...

    java实现网页爬虫的示例讲解

    Java实现网页爬虫的示例讲解 Java语言是目前最流行的编程语言之一,对于爬虫的实现提供了极大的便利性。爬虫是数据采集的一种方法,实际项目开发中,通过爬虫做数据采集一般只有以下几种情况:搜索引擎、竞品调研、...

    爬虫程序爬虫程序 java 数据挖掘

    根据给定文件的信息,我们可以提炼出以下关于Java爬虫程序及数据挖掘的相关知识点: ### Java爬虫程序概览 #### 一、Sosoo爬虫框架简介 Sosoo是一款用Java编写的开源网络爬虫框架,适用于进行大规模的数据抓取任务...

    基于java实现浅度爬虫应用

    浅度爬虫是相对于深度爬虫而言的,它主要集中在网站表面的页面,通常用于获取网页的元数据或者对特定领域的信息进行快速索引。本项目基于Java编程语言,为初学者提供了一个简单的入门实践,旨在帮助理解如何构建一个...

    完整版基于java语言实现的广度优先算法多线程爬虫程序网络爬虫毕业设计报告共69页.rar

    这篇毕业设计报告主要聚焦在使用Java语言实现一个基于广度优先搜索(BFS)算法的多线程网络爬虫程序。网络爬虫是自动化获取互联网信息的重要工具,它能够遍历网页并抓取所需数据。Java作为一种通用且跨平台的编程...

    crawler4j是Java实现的开源网络爬虫

    - **深度优先与广度优先**:支持两种常见的网页遍历策略,即深度优先搜索(DFS)和广度优先搜索(BFS)。 - **URL管理**:自动管理已访问、待访问和忽略的URL,避免重复爬取和无限循环。 - **下载策略**:可以...

    爬虫搜索,简单的搜索引擎,java爬虫,搜索引擎例子,爬虫demo,java实现互联网内容抓取,搜索引擎大揭密

    例如,`demo`可能是一个简单的Java爬虫程序示例,它可能包括以下几个关键步骤: 1. **初始化配置**:设置起始URL、爬取深度、延迟时间等参数。 2. **网页请求**:使用HTTP客户端发送GET请求,获取网页HTML响应。 3....

    图的深度和广度优先遍历源程序及实验报告还有PPt

    在这个场景中,我们关注的是图数据结构的一种遍历方法——深度优先搜索(DFS)和广度优先搜索(BFS)。这两种算法在解决实际问题如路径查找、网络爬虫、社交网络分析等方面有着广泛应用。 深度优先遍历是一种用于...

    实现深度优先广度优先算法

    深度优先搜索(DFS, Depth-First Search)和广度优先搜索(BFS, Breadth-First Search)是图论中的两种基本搜索策略,用于遍历或搜索树或图。这两种算法在解决各种问题中有着广泛的应用,如路径查找、判断连通性、...

    java网络蜘蛛示例程序

    8. **算法与数据结构**:如队列(Queue)用于存储待抓取的URL,优先队列(PriorityQueue)用于根据某种策略(如深度优先或广度优先)决定下一个要抓取的URL。 9. **网络协议**:了解HTTP、HTTPS等网络协议的基本...

    列磁盘目录(深度优先和广度优先实现)

    这篇博客“列磁盘目录(深度优先和广度优先实现)”探讨了两种不同的算法来遍历和列出磁盘目录结构:深度优先搜索(DFS)和广度优先搜索(BFS)。这两种方法在遍历树形或图状结构时各有优势,这里我们将深入理解它们...

    用java写的爬虫代码

    这个简单的 Java 爬虫程序提供了一个基本的框架,你可以根据需要扩展其功能,例如加入深度优先或广度优先的搜索策略,实现更精细的 URL 去重机制,或者增加对其他协议的支持。在实际应用中,还需要注意遵守网站的...

    java源码:Java网页爬虫 JSpider.zip

    6. **爬虫框架设计**:理解如何组织和设计爬虫框架,包括URL管理、任务调度、深度优先或广度优先搜索策略等。 7. **IP代理与反反爬策略**:应对网站的反爬机制,如使用IP代理池,模拟浏览器行为,设置User-Agent,...

    网络爬虫网络爬虫

    - **爬虫策略**:包括深度优先和广度优先,以及如何避免陷入无限循环或者重复抓取同一页面。 - **爬虫速率控制**:为了避免对目标网站造成过大压力,需要设置合理的请求间隔和并发数。 - **反爬机制**:很多网站有...

    Java爬虫实战训练源码

    5. 跟踪链接:如果需要抓取整个网站,爬虫需要识别并访问页面上的链接,进行深度爬取。 在Java爬虫实战训练中,我们可能还会涉及到反爬策略的应对,如设置User-Agent、Cookies,模拟登录,以及处理验证码和动态加载...

    搜索链接Java网络爬虫(蜘蛛)源码-zhizhu.rar

    6. **重复步骤2-5**:根据预定义的规则(如深度优先、广度优先)和链接队列,继续爬取其他页面。 7. **异常处理**:处理可能出现的网络错误、编码问题、重定向、登录验证等情况。 【法律与道德考虑】 在进行网络...

Global site tag (gtag.js) - Google Analytics