我正在尝试抓取300,000个网址。但是,在中间的某个位置,代码在尝试从URL检索响应代码时会挂起。我不确定自从建立连接以来出现了什么问题但是之后问题就出现了。我修改了设置读取超时的代码和建议的请求属性。但是,即使现在代码也无法获取响应代码! 任何建议/指针将不胜感激。此外,有没有办法ping一个网站一段时间,如果它没有响应只是继续下一个?
以下是我修改过的代码段:
URL url=null;
try
{
Thread.sleep(8000);
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
try
{
//urlToBeCrawled comes from the database
url=new URL(urlToBeCrawled);
}
catch (MalformedURLException e)
{
e.printStackTrace();
//The code is in a loop,so the use of continue.I apologize for putting code in the catch block.
continue;
}
HttpURLConnection huc=null;
try
{
huc = (HttpURLConnection)url.openConnection();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
//Added the request property
huc.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
huc.setRequestMethod("HEAD");
}
catch (ProtocolException e)
{
e.printStackTrace();
}
huc.setConnectTimeout(1000);
try
{
huc.connect();
}
catch (IOException e)
{
e.printStackTrace();
continue;
}
int responseCode=0;
try
{
//Sets the read timeout
huc.setReadTimeout(15000);
//Code hangs here for some URL which is random in each run
responseCode = huc.getResponseCode();
}
catch (IOException e)
{
huc.disconnect();
e.printStackTrace();
continue;
}
if (responseCode!=200)
{
huc.disconnect();
continue;
}
答案 0 :(得分:0)
在调用url.openConnection()打开连接后,您将在HttpURLConnection上设置读取和连接超时。因此它们没有生效。我可能会将Jetty HttpClient用于此目的而不是Java URL类。
回答你的第二点。是的,只需尝试打开与远程域名的端口80(或URL中指定的其他端口)的连接,您可以使用原始套接字从URL(使用url.getHost()
)中提取该端口。为此,我将使用Netty而不是Java套接字。
答案 1 :(得分:0)
它挂起是因为从未在字节流中收到响应代码。您将需要查看http调试器并查看实际收到的内容,如果有的话。但它似乎打开了与服务器的TCP连接。它可能不喜欢您的用户代理(可能没有设置为您认为的那样)或HEAD
的请求方法,或者它可能是带宽有限的服务器。您可以使用Socket
类来打开连接并手动准备字节以查看您正在接收的内容。
另一方面,仅使用Socket
实际上不是一种糟糕的方法取决于您想要做什么。 听起来就像你正在编写一个http服务器检查程序一样,在这种情况下,你可以直接使用Socket
获得更多功能,因为你将能够设计出更好,更优化的技术(毕竟你正在使用大量的低级别网络。