URLConnection nie pozwala mi na dostęp do danych o błędach Http (404,500,etc)

Robię crawler i muszę pobrać dane ze strumienia niezależnie od tego, czy jest to 200, czy nie. CURL to robi, podobnie jak każda standardowa przeglądarka.

Poniżej nie zostanie wyświetlona treść żądania, nawet jeśli jest kilka, zostanie wyrzucony wyjątek z kodem stanu błędu http. Chcę wyjść bez względu na to, czy jest jakiś sposób? Wolę korzystać z tej biblioteki, ponieważ faktycznie będzie to robić trwałe połączenia, co jest idealne dla typu crawling jestem robiąc.

package test;

import java.net.*;
import java.io.*;

public class Test {

    public static void main(String[] args) {

         try {

            URL url = new URL("http://github.com/XXXXXXXXXXXXXX");
            URLConnection connection = url.openConnection();

            DataInputStream inStream = new DataInputStream(connection.getInputStream());
            String inputLine;

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.err.println("IOException: " + ioe);
        }
    }
}

Działa, dzięki: oto co wymyśliłem-tylko jako przybliżony dowód koncepcji:

import java.net.*;
import java.io.*;

public class Test {

    public static void main(String[] args) {
//InputStream error = ((HttpURLConnection) connection).getErrorStream();

        URL url = null;
        URLConnection connection = null;
        String inputLine = "";

        try {

            url = new URL("http://verelo.com/asdfrwdfgdg");
            connection = url.openConnection();

            DataInputStream inStream = new DataInputStream(connection.getInputStream());

            while ((inputLine = inStream.readLine()) != null) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.err.println("IOException: " + ioe);

            InputStream error = ((HttpURLConnection) connection).getErrorStream();

            try {
                int data = error.read();
                while (data != -1) {
                    //do something with data...
                    //System.out.println(data);
                    inputLine = inputLine + (char)data;
                    data = error.read();
                    //inputLine = inputLine + (char)data;
                }
                error.close();
            } catch (Exception ex) {
                try {
                    if (error != null) {
                        error.close();
                    }
                } catch (Exception e) {

                }
            }
        }

        System.out.println(inputLine);
    }
}
Author: MichaelICE, 2012-02-03

2 answers

Proste:

URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
if (connection instanceof HttpURLConnection) {
   HttpURLConnection httpConn = (HttpURLConnection) connection;
   int statusCode = httpConn.getResponseCode();
   if (statusCode != 200 /* or statusCode >= 200 && statusCode < 300 */) {
     is = httpConn.getErrorStream();
   }
}

Możesz odnieść się do Javadoc w celu wyjaśnienia. Najlepiej bym sobie z tym poradził:

URLConnection connection = url.openConnection();
InputStream is = null;
try {
    is = connection.getInputStream();
} catch (IOException ioe) {
    if (connection instanceof HttpURLConnection) {
        HttpURLConnection httpConn = (HttpURLConnection) connection;
        int statusCode = httpConn.getResponseCode();
        if (statusCode != 200) {
            is = httpConn.getErrorStream();
        }
    }
}
 41
Author: Buhake Sindi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 10:17:26

Musisz wykonać następujące czynności po wywołaniu openConnection.

  1. Wyślij URLConnection do HttpURLConnection

  2. Wywołanie getResponseCode

  3. Jeśli odpowiedź się powiedzie, użyj getInputStream, w przeciwnym razie użyj getErrorStream

(test na sukces powinien być 200 <= code < 300, ponieważ istnieją ważne kody sukcesu HTTP oprócz 200.)


Robię crawler i muszę pobrać dane ze strumienia niezależnie od tego, czy jest 200 albo nie.

Należy pamiętać, że jeśli kod jest 4xx lub 5xx ,to" dane " prawdopodobnie będzie stroną błędu jakiegoś rodzaju.


Ostatnim punktem, który powinien być wykonany jest to, że należy zawsze szanować " roboty.txt " plik ... i przeczytaj Warunki korzystania z serwisu przed indeksowaniem / skrobaniem treści strony, której właściciele mogą dbać. Samo wyzwalanie żądań GET może denerwować właścicieli witryn ... chyba, że już doszedłeś do jakiegoś "układ" z nimi.

 9
Author: Stephen C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-30 02:14:22