java 多线程下载 爬虫 urlconnection超时

黑man巴 发布于 2013/08/07 09:48
阅读 1K+
收藏 0
用以下代码从一个list里取出url进行网页下载,但是有得网页连接超时,或者读取数据超时,怎么样设置个时间,如果在这个时间内没下载完成就重新连接,或者放弃这个页面的下载

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpDownloader implements Callable<String> {
    URLConnection connection;
    FileChannel outputChann;
    public static volatile int count = 0;

    public static void main(String[] args) throws Exception {
    	
    	
		List<PageBean> list = new ArrayList<PageBean>();
		for (int i = 0; i <= 300; i++) {
			list = DBmanager.exportUrForDownloadFromDB(i);
			System.out.println(list.size());
			ExecutorService poll = Executors.newFixedThreadPool(100);
			for (int j = 0; j < list.size(); j++) {
				String s = String.valueOf(list.get(j).getId()) + ".html";
				String fileName = "f:/采集网页标签数据/"+s;    
				
		
				String url = list.get(j).getUrl();
				System.out.println(url);		
				poll.submit(new HttpDownloader(url, new FileOutputStream(fileName).getChannel()));
			}
			poll.shutdown();
			long start = System.currentTimeMillis();
	        while (!poll.isTerminated()) {
	            Thread.sleep(1000);
	            System.out.println("已运行"
	                    + ((System.currentTimeMillis() - start) / 1000) + "秒,"
	                    + HttpDownloader.count + "个任务还在运行");
	        }
	        list.clear();
		}
    	
}
    	
    public HttpDownloader(String url, FileChannel fileChannel) throws Exception {
        synchronized (HttpDownloader.class) {
            count++;
        }
        connection = (new URL(url)).openConnection();
        System.out.println("URL(url)).openConnection()");
        this.outputChann = fileChannel;
    }

    @Override
    public String call() throws Exception {
        connection.connect();
        System.out.println("connection.connect()");
        InputStream inputStream = connection.getInputStream();
        ReadableByteChannel rChannel = Channels.newChannel(inputStream);
        outputChann.transferFrom(rChannel, 0, Integer.MAX_VALUE);
        // System.out.println(Thread.currentThread().getName() + " completed!");
        inputStream.close();
        outputChann.close();
        synchronized (HttpDownloader.class) {
            count--;
        }
        return null;
    }
}
加载中
0
马太航
马太航
跟爬虫关系不大 就一多线程瞎子啊
0
袁不语
袁不语

URLConnection有个setConnectTimeout方法可以试一下。

黑man巴
@袁不语 谢谢指导我改进改进
袁不语
袁不语
回复 @黑man巴 : connection在你代码中不是多线程共享的,放哪里都行呀。我觉得会超时的原因可能是下载任务起的太多了,而线程池只有100,很多任务就处于pending状态,而且在constructor中就已经建立了连接,所有就很容易超时。建议1.把建立连接的逻辑放到call中;2.先把并发的下载任务适当减少一点儿调试程序,稍后再增加。
黑man巴
这个我知道,但是我不知道在多线程的情况下 connection.setConnectTimeout(60000); connection.setReadTimeout(60000); 该放在call() 方法里还是哪里。。。。
0
黑man巴
爬虫的一部分啦,截取出来测试的,多线程 超时的处理你会么 我对多线程不太懂
0
掌心
掌心
建立的connection不用关闭吗?太耗资源了
返回顶部
顶部