完成页面下载时候,就要分析代码,提取出里面的链接。提取的基本思路当然是通过正则来提取。但是可能遇到两种情况:
1:绝对链接:例如http://catcoder.com
2:相对链接:例,image/1.jpg
在相对链接的时候就要知道链接的上级目录。但是在之前下载页面的时候,没有保存URL,所以需要修改(当时考虑的太不全面)。
//第一行写入网址 sbPage.append(url); sbPage.append("\n");
把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链接。