我需要在网上阅读大量的网页。这是我实际上用来获取远程网页的方法。请注意,当前代码是100%工作。
static private GetWebPageResult getWebPage(PageNode pagenode)
{
String result;
String inputLine;
URI url;
int cicliLettura=0;
long startTime=0, endTime, openConnTime=0,connTime=0, readTime=0;
try
{
startTime=System.nanoTime();
result="";
url=pagenode.getUri(); //fare qualcosa se getURI è null
if(Core.logGetWebPage())
openConnTime=System.nanoTime();
if(url!=null)
{
HttpURLConnection yc = (HttpURLConnection) url.toURL().openConnection(); //controllare yc
if(url.toURL().getProtocol().equalsIgnoreCase("https"))
yc=(HttpsURLConnection)yc;
yc.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)");
yc.connect(); //controllare il risultato di .connect => non c'è! al max lancia IOEXC
if(checkResponseCode(yc.getResponseCode())==false)
return new GetWebPageResult(GetWebPageResult.ERR_BAD_RESPONSE_CODE,yc.getResponseCode());
if(Core.logGetWebPage())
connTime=System.nanoTime();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));//può lanciare IOEXC
/*
while ((inputLine = in.readLine()) != null)
{
result=result+inputLine+"\n";
cicliLettura++;
}*/
StringBuffer buffer = new StringBuffer();
while ((inputLine = in.readLine()) != null)
{
buffer.append(inputLine).append('\n');
cicliLettura++;
}
result = buffer.toString();
if(Core.logGetWebPage())
readTime=System.nanoTime();
in.close();
yc.disconnect();
if(Core.logGetWebPage())
{
endTime=System.nanoTime();
//url.toURL() non è null, controllato prima
System.out.println(/*result+*/"getWebPage eseguito in "+(endTime-startTime)/1000000+" ms. Size: "+result.length()+" Response Code="+yc.getResponseCode()+" Protocollo="+url.toURL().getProtocol()+" openConnTime: "+(openConnTime-startTime)/1000000+" connTime:"+(connTime-openConnTime)/1000000+" readTime:"+(readTime-connTime)/1000000+" cicliLettura="+cicliLettura+" pagina:"+url.toURL());
}
return new GetWebPageResult(result);
}
else
return new GetWebPageResult(GetWebPageResult.ERR_NULL_URI,-2);
}catch(IOException e){
System.out.println("Eccezione1: "+e.toString());
e.printStackTrace();
return new GetWebPageResult(GetWebPageResult.ERR_HTML_IOEXCEPTION,-2);
}catch(ClassCastException e){
System.out.println("Eccezione2: "+e.toString());
e.printStackTrace();
return new GetWebPageResult(GetWebPageResult.ERR_CLASS_CAST_EXC,-2);
}catch(Exception e){
System.out.println("Eccezione ERR_NOT_LISTED_EXC: "+e.toString());
return new GetWebPageResult(GetWebPageResult.ERR_NOT_LISTED_EXC,-2);
}
}考虑到url不是空的,让我们仔细看看代码
HttpURLConnection yc = (HttpURLConnection) url.toURL().openConnection(); //controllare yc
if(url.toURL().getProtocol().equalsIgnoreCase("https"))
yc=(HttpsURLConnection)yc;
yc.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)");
yc.connect(); //controllare il risultato di .connect => non c'è! al max lancia IOEXC
if(checkResponseCode(yc.getResponseCode())==false)
return new GetWebPageResult(GetWebPageResult.ERR_BAD_RESPONSE_CODE,yc.getResponseCode());.openConnection和.connect方法有什么区别?无论如何,当我们打开一个连接时,我们就开始读取数据。
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));//può lanciare IOEXC
StringBuffer buffer = new StringBuffer();
while ((inputLine = in.readLine()) != null)
{
buffer.append(inputLine).append('\n');
cicliLettura++;
}
result = buffer.toString();现在我有了一个BufferedReader来读取数据。问题是,我的带宽通常比远程机器的带宽要大得多,所以我希望能够“同时”从不同的来源读取信息。一种很好的方法似乎可以启动许多线程,并像下面这样修改代码的最后一部分
虽然没有结束文件,那么是否有完整的行可读取?如果是的话,问一个新的行,否则睡一会儿。在这一点上,我继续下一个阅读线程,并做出同样的事情。这是正确的吗?如何实现这一点?
发布于 2014-05-25 17:14:37
这看起来像是一个典型的生产者/消费者场景。您可以通过创建以下类来优化应用程序。如果您还不知道BlockingQueue的概念和生产者-消费者问题,我建议您在继续我的回答/设计之前阅读这。
现在所需要做的就是将PageNode对象添加到ProcessingQueue中,启动WebPageReader和WebPageProcessor线程,并观察奇迹的发生。如果你需要澄清的话请告诉我。根据您的需求,您可以选择只启动一个WebPageReader线程和WebPageProcessor线程或多个线程。该设计支持两者。另外,您还可以引入一个线程,通过爬行Web或轮询某种数据库来将PageNode对象添加到ProcessingQueue中,以查找要爬行的页面。
https://stackoverflow.com/questions/23856666
复制相似问题