2 yzn77 yzn77 于 2016.05.03 18:36 提问

网络爬虫下载网页的问题

下载网页时只能下载第一个网页,后续网页虽然能爬出来,但是无法下载到本地。下载网页的代码如下
public class FileDownLoader {
/**根据 url 和网页类型生成需要保存的网页的文件名
去除掉 url 中非文件名字符
*/
public String getFileNameByUrl(String url,String contentType)
{
url=url.substring(7);//remove http://
if(contentType.indexOf("html")!=-1)//text/html
{
url= url.replaceAll("[\?/:
|<>\"]", "_")+".html";
return url;
}
else//如application/pdf
{
return url.replaceAll("[\?/:*|<>\"]", "_")+"."+

      contentType.substring(contentType.lastIndexOf("/")+1);
    }   
}

/**保存网页字节数组到本地文件
 * 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 (IOException e) {
e.printStackTrace();
}
}

/*下载 url 指向的网页*/
public String  downloadFile(String url)
{
      String filePath=null;


     /* 使用 GetMethod 来访问一个 URL 对应的网页,需要如下一些步骤。
      1 生成一个 HttpClinet 对象并设置相应的参数。
      2 生成一个 GetMethod 对象并设置响应的参数。
      3 用 HttpClinet 生成的对象来执行 GetMethod 生成的 Get 方法。
      4 处理响应状态码。
      5 若响应正常,处理 HTTP 响应内容。
      6 释放连接*/
      /* 1.生成 HttpClinet 对象并设置参数*/
      HttpClient httpClient=new HttpClient();
      //设置 Http 连接超时 5s
          httpClient.getHttpConnectionManager().getParams().

setConnectionTimeout(5000);

      /*2.生成 GetMethod 对象并设置参数*/
      //使用 GetMethod 来访问一个 URL 对应的网页
      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{ 
          /*executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码,
          该状态码能表示出该方法执行是否成功,需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳转的)*/
          int statusCode = httpClient.executeMethod(getMethod);
          //判断访问的状态码
          if (statusCode != HttpStatus.SC_OK) 
          {

System.err.println("Method failed: "+ getMethod.getStatusLine());
filePath=null;
}

          /*4.处理 HTTP 响应内容(返回的状态码正确后,即可取得内容)*/
          /*取得目标地址的内容有三种方法:
          1 getResponseBody,该方法返回的是目标的二进制的byte流;
          2 getResponseBodyAsString,返回的是String类型,值得注意的是该方法返回的String的编码是根据系统默认的编码方式,所以返回的String值可能编码类型有误
          3 getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。
                  在这里我们使用了最简单的getResponseBody方法。*/

byte[] responseBody = getMethod.getResponseBody();//读取为字节数组
//根据网页 url 生成保存时的文件名
filePath="E:\java\web spider\"+getFileNameByUrl(url,
getMethod.getResponseHeader("Content-Type").getValue());
saveToLocal(responseBody,filePath);
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
} catch (IOException e) {
// 发生网络异常
e.printStackTrace();
} finally {
// 释放连接
getMethod.releaseConnection();

}
return filePath;
}
}
调用他的爬行代码如下:
public class Crawler {
/* 使用种子 url 初始化 URL 队列*/
String results="";
private void initCrawlerWithSeeds(String[] seeds)
{
for(int i=0;i<seeds.length;i++)
LinkDB.addUnvisitedUrl(seeds[i]);
}

/* 爬取方法*/
public void crawling(String[] seeds,JTextArea kkk)
{
    LinkFilter filter = new LinkFilter(){
        //提取以 用户输入的URL开头的链接
        public boolean accept(String url) {
            if(url.startsWith(url))
                return true;
            else
                return false;
        }
    };
    //初始化 URL 队列
    initCrawlerWithSeeds(seeds);
    //循环条件:待抓取的链接不空且抓取的网页不多于 1000
    while(!LinkDB.unVisitedUrlsEmpty()&&LinkDB.getVisitedUrlNum()<=1000)
    {
        //队头 URL 出对
        String visitUrl=LinkDB.unVisitedUrlDeQueue();
        if(visitUrl==null)
            continue;
        FileDownLoader downLoader=new FileDownLoader();
        //下载网页
        downLoader.downloadFile(visitUrl);
        //该 url 放入到已访问的 URL 中
        LinkDB.addVisitedUrl(visitUrl);
        //提取出下载网页中的 URL

        Set<String> links=HtmlParserTool.extractLinks(visitUrl,filter);
    Iterator<String> it = links.iterator(); //迭代器
        while(it.hasNext())
        {  
            results=results+'\n'+it.next();

        }

     kkk.setText(results);


    }
}

}
求各位大神帮忙解答,马上就要中期检查了

2个回答

devmiao
devmiao   Ds   Rxr 2016.05.04 07:12
已采纳
CSDNXIAOD
CSDNXIAOD   2016.05.03 18:41

网络爬虫下载网页
网络爬虫系列之一:通过URL下载网页
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!