7

サイトの複数のページからコンテンツを取得するアプリケーションを作成しようとしています。JSoupを使用して接続しています。これは私のコードです:

for (String locale : langList){
        sitemapPath = sitemapDomain+"/"+locale+"/"+sitemapName;
        try {
            Document doc = Jsoup.connect(sitemapPath)
                    .userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.21 (KHTML, like Gecko) Chrome/19.0.1042.0 Safari/535.21")
                    .timeout(10000)
                    .get();

            Elements element = doc.select("loc");   
            for (Element urls : element) {
                System.out.println(urls.text());
                }
        } catch (IOException e) {
            System.out.println(e);
        }
    }

ほとんどの場合、すべてが完全に機能します。しかし、私がやりたいことがいくつかあります。

まず、404ステータスが返されることもあれば、500ステータスが301になることもあります。以下の私のコードでは、エラーが出力され、次のURLに移動します。私ができるようにしたいのは、すべてのリンクのURLステータスを返すことができるようにすることです。ページが接続されている場合は200を印刷し、そうでない場合は関連するステータスコードを印刷します。

次に、このエラー「java.net.SocketTimeoutException:Read timed out」が発生することがありますが、タイムアウトを増やすことはできますが、3回失敗すると、「失敗した」配列にURLを追加したいので3回接続を試みます。後で失敗した接続を再試行できます。

私よりも知識のある人が私を助けてくれますか?

4

2 に答える 2

19

上記は、execute()が正しいステータスコードを返すのではなく、IOExceptionを返します。

JSoup -1.6.1を使用すると、 ignoreHttpErrors(true)を使用するように上記のコードを変更する必要がありました。

これで、コードが例外をスローするのではなく応答を返し、エラーコード/メッセージを確認できるようになりました。

Connection.Response response = null;
            try {
                response = Jsoup.connect(bad_url)
                        .userAgent("Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5")
                        .timeout(100000)
                        .ignoreHttpErrors(true) 
                        .execute();
            } catch (IOException e) {
                System.out.println("io - "+e);
            }

            System.out.println("Status code = " + response.statusCode());   
            System.out.println("Status msg  = " + response.statusMessage());

出力:

Status code = 404
Status msg  = Not Found
于 2012-05-24T13:10:00.317 に答える
16

最初の質問では、接続/読み取りを2つのステップで実行し、次のように途中でステータスコードを要求するのをやめることができます。

Connection.Response response = Jsoup.connect(sitemapPath)
                        .userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.21 (KHTML, like Gecko) Chrome/19.0.1042.0 Safari/535.21")
                        .timeout(10000)
                        .execute();

int statusCode = response.statusCode();
if(statusCode == 200) {
    Document doc = connection.get();
    Elements element = doc.select("loc");   
    for (Element urls : element) {
        System.out.println(urls.text());
    }
}
else {
    System.out.println("received error code : " + statusCode);
}

サーバーに接続できない場合、応答が不正な形式のHTTPである場合など、execute()メソッドは失敗することに注意してください。そのため、これを処理する必要があります。IOExceptionただし、サーバーが意味のあることを言っている限り、ステータスコードを読み取って続行することができます。また、リダイレクトに従うようにJsoupに依頼した場合、30x応答コードは表示されません。b/ c Jsoupは、フェッチされた最後のページからステータスコードを設定します。

2番目の質問については、必要なのは、先ほど提供したコードサンプルの周りのループです。これは。を含むtry/catchブロックでラップされていSocketTimeoutExceptionます。例外をキャッチすると、ループが続行されます。データを取得できる場合は、戻るか中断します。さらにサポートが必要な場合は、叫んでください。

于 2012-04-20T14:38:24.663 に答える