Код зависает при попытке получить код ответа

Я пытаюсь просканировать 300 000 URL-адресов. Однако где-то посередине код зависает при попытке получить код ответа из URL-адреса. Я не уверен, что происходит не так, так как соединение устанавливается, но проблема возникает после этого. Любые предложения / указатели будут с благодарностью. Кроме того, есть ли способ пропинговать веб-сайт в течение определенного периода времени, и если он не отвечает, просто перейдите к следующему?

Я изменил код в соответствии с предложениями, установив время ожидания чтения и свойство запроса, как было предложено. Однако даже сейчас код не может получить код ответа!

Вот мой измененный фрагмент кода:

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;
}

person collegian    schedule 21.04.2011    source источник


Ответы (2)


Это действительно должно быть сделано с использованием многопоточности. Особенно если вы пытаетесь использовать 300 000 URL-адресов. Я предпочитаю подход с пулом потоков для этого.

Во-вторых, вы действительно выиграете от более надежного HTTP-клиента, такого как http-клиент apache commons, поскольку он может лучше устанавливать пользовательский агент. Принимая во внимание, что большинство JRE не позволят вам изменить пользовательский агент с помощью класса HttpURLConnection (они заставляют его использовать вашу версию JDK, например: Java/1.6.0_13 будет вашим пользовательским агентом). Есть уловки, чтобы изменить это, настроив системное свойство, но Я никогда не видел, чтобы это действительно работало. Снова используйте HTTP-библиотеку Apache Commons, не пожалеете.

Наконец, вам нужен хороший http-отладчик, чтобы справиться с этим в конечном итоге. Вы можете использовать Fiddler2 и просто настройте прокси-сервер Java, чтобы он указывал на fiddler (прокрутите до раздела о Java).

person Zombies    schedule 22.04.2011
comment
Спасибо за ответ. Я посмотрю на них! - person collegian; 22.04.2011

Сервер держит соединение открытым, но также не отвечает. Он может даже обнаруживать, что вы просматриваете их сайт, а брандмауэр или инструменты защиты от DDOS намеренно пытаются вас запутать. Убедитесь, что вы установили пользовательский агент (некоторые серверы рассердятся, если вы этого не сделаете). Кроме того, установите тайм-аут чтения, чтобы, если он не сможет прочитать через некоторое время, он сдастся:

huc.setReadTimeout(15000);
person squawknull    schedule 21.04.2011
comment
Спасибо за ответ. Можете ли вы указать мне ресурс, в котором описывается, как настроить пользовательский агент? - person collegian; 21.04.2011
comment
@collegian - это просто заголовок запроса: w3.org/ Протоколы/rfc2616/rfc2616-sec14.html#sec14.43 - person Stephen C; 21.04.2011
comment
@Stephen @squawknull Спасибо за ответ. - person collegian; 21.04.2011
comment
Я считаю, что readTimeout будет работать только в том случае, если установлено фактическое соединение и байты могут начать потоковую передачу. Вам также нужно будет установить меньшее время ожидания соединения. (например: setConnectTimeout(int timeout)) - person Zombies; 22.04.2011