1

我正在尝试抓取 300,000 个 URL。但是,在尝试从 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;
}
4

2 回答 2

1

服务器保持连接打开,但也没有响应。它甚至可能检测到您正在爬取他们的站点,并且防火墙或反 DDOS 工具故意试图混淆您。确保你设置了一个用户代理(如果你不这样做,一些服务器会生气)。另外,设置读取超时,这样如果一段时间后读取失败,它将放弃:

huc.setReadTimeout(15000);
于 2011-04-21T04:49:33.133 回答
0

这确实应该使用多线程来完成。特别是如果您尝试 300,000 个 URL。我更喜欢线程池方法

其次,您将真正受益于更强大的 HTTP 客户端,例如 apache commons http 客户端,因为它可以更好地设置用户代理。而大多数 JRE 不允许您使用HttpURLConnection该类修改用户代理(他们将其强制为您的 JDK 版本,例如:Java/1.6.0_13将成为您的用户代理。)有一些技巧可以通过调整系统属性来改变这一点,但我有从未见过实际工作。再次使用 Apache Commons HTTP 库,你不会后悔的。

最后,您需要一个好的 http 调试器来最终处理这个问题,您可以使用Fiddler2,只需设置一个 java 代理以指向 fiddler(滚动到有关 Java 的部分)。

于 2011-04-22T16:15:04.527 回答