zoukankan      html  css  js  c++  java
  • 自己圈养小爬虫(二)——提取链接1

    完成页面下载时候,就要分析代码,提取出里面的链接。提取的基本思路当然是通过正则来提取。但是可能遇到两种情况:
     
    1:绝对链接:例如http://catcoder.com
    2:相对链接:例,image/1.jpg
     

    在相对链接的时候就要知道链接的上级目录。但是在之前下载页面的时候,没有保存URL,所以需要修改(当时考虑的太不全面)。

    //第一行写入网址
    sbPage.append(url);
    sbPage.append("
    ");

    把URL写入文件的第一行,读取的时候对应读取即可。但是这时又有一个问题出现:链接中可能有汉字。
     
    上次在下载文件的时候,直接用的是UTF-8格式,那是对应catcoder这个blog来说,确实没有问题,但其他网站未必都是这个格式,还有GBK等,所以就应该读取网页的编码。
     
    试了几种方法,后来还是自己截取来的放心,但是有可能没有数据,那就不写编码……但是通常情况下,中文的网站都会有编码格式,不然网页都不一定能正常加载。

    /**
     * 获取编码
     */
    private void getEncoding(){
        String contentType = urlConnection.getContentType();
        if(contentType != null && contentType.indexOf("charset") > 0){
            contentType = contentType.substring(contentType.indexOf("charset") + 8);
            urlEncoding = contentType;
        }else{
            urlEncoding = "";
        }
    }

     

    然后在下载的时候判断编码:

    getEncoding();
    if(urlEncoding != ""){
        reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), urlEncoding));
    }else{
        reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
    }

    这时候有个问题需要解决,如何让保存URL列表,如何保存Image列表,如何保持文件列表。这样在程序运行的时候才可以自动去完成。

     
    在这里我暂时先决定用BlockingQueue来做,BlockingQueue是多线程的,方便多线程操作,而且操作起来也比较方便,问题就是无法确认链接是否被下载过,但是我觉得先制造一个可用的小爬虫的话,这些事可以忍受的。
     

    所以创建一个URLFactory.java类,用来存储容器:

    public static int DEFAULT_NUM = 1000;
    public static int URL_NUM = 1000;
    public static int FILE_NUM = 1000;
    public static int IMAGE_NUM = 1000;
    /**
    * 从文件中取出的URL链接容器
    */
    public static BlockingQueueURL_LIST = new ArrayBlockingQueue(DEFAULT_NUM);
    /**
    * 根据URL_LIST下载网页并保存文件名的容器
    */
    public static BlockingQueueFILE_LIST = new ArrayBlockingQueue(DEFAULT_NUM);
    /**
    * 从文件中取出的图片地址,等待下载
    */
    public static BlockingQueueIMAGE_LIST = new ArrayBlockingQueue(DEFAULT_NUM);
    /**
    * 初始化容器的容量,默认值为1000
    */
    public URLFactory(){
    }
    /**
    * 自定义容器的容量
    * @param urlnum
    * @param filenum
    * @param imagenum
    */
    public URLFactory(int urlnum, int filenum, int imagenum){
        URL_NUM = urlnum;
        FILE_NUM = filenum;
        IMAGE_NUM = imagenum;
        URL_LIST = new ArrayBlockingQueue(URL_NUM);
        FILE_LIST = new ArrayBlockingQueue(FILE_NUM);
        IMAGE_LIST = new ArrayBlockingQueue(IMAGE_NUM);
    }

    先确定三个容器,然后所有的操作都通过这三个容器交换数据。

     
    接下来就可以创建GetURL.java类来提取链接了。
     
    提前的第一步就是加载已经保存好的文件: 

    BufferedReader br = new BufferedReader(
            new FileReader(new File(fileName).getAbsoluteFile()));

    为了防止相对路径的情况发生,先要获取到URL目录: 

    /**
    * 处理来源URL,得到URL目录
    */
    private void getRootURL(){
        if(fromURL.indexOf("/", 8) > 0){
            fromURL = fromURL.substring(0, fromURL.lastIndexOf("/") + 1);
        }else{
            fromURL = fromURL + "/";
        }
    }

    regexURL(String)方法就是解析HTML代码得到URL的关键方法,目前只是提取出href属性,并没有做进一步的处理。 
    目前阶段提取到的数据如下:

    提取到URL--------Star
    href="http://catcoder.com/"
    href="http://catcoder.com/my/mymark.html"
    href="http://catcoder.com/category/real-software/"
    ·
    ·
    ·
    href="http://catcoder.com/comments/feed/"
    href="http://cn.wordpress.org/"
    href="http://www.tutorialchip.com/"
    href="http://wordpress.org/"
    提取到URL--------End

     
    第一阶段先到这里,下次就是提取出有效URL,并且提取出Image链接。

  • 相关阅读:
    JavaScript算法系列之-----------------斐波那契数列(JS实现)
    js中Math.max()求取数组中最大值
    JavsScript中比较大小总结---基于sort()方法
    前端技能大挑战-3(修改this指向)
    前端技能大挑战-2(数组去重)
    前端技能大挑战-1(驼峰命名)
    JavaScript算法系列之-----------------链表反转(JS实现)
    JavaScript算法系列之-----------------字符串排列(JS实现)
    JavaScript算法系列之-----------------替换空格(JS实现)
    JavaScript算法系列之-----------------二维数组中的查找(JS实现)
  • 原文地址:https://www.cnblogs.com/mnight/p/3677649.html
Copyright © 2011-2022 走看看