【问题标题】:Handling connection errors and JSoup处理连接错误和 JSoup
【发布时间】:2012-05-01 23:55:55
【问题描述】:

我正在尝试创建一个应用程序来从网站上的多个页面中抓取内容。我正在使用 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:读取超时”我可以增加我的超时但是我更愿意尝试连接 3 次,在第三次失败时我想将 URL 添加到“ failed" 数组,以便我以后可以重试失败的连接。

有比我知识渊博的人帮帮我吗?

【问题讨论】:

    标签: java connection jsoup


    【解决方案1】:

    对于您的第一个问题,您可以分两步进行连接/读取,停止询问中间的状态码,如下所示:

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

    请注意,如果execute() 方法无法连接到服务器,或者响应格式错误的 HTTP 等,则该方法将失败并返回 IOException,因此您需要进行处理。但是,只要服务器说出有意义的话,您就可以读取状态码并继续。此外,如果您已要求 Jsoup 跟踪重定向,您将不会看到 30x 响应代码 b/c Jsoup 将从获取的最终页面设置状态代码。

    至于您的第二个问题,您所需要的只是围绕我刚刚提供给您的代码示例的循环,该代码示例包含一个带有 SocketTimeoutException 的 try/catch 块。当您捕获异常时,循环应该继续。如果您能够获取数据,则返回或中断。如果您需要更多帮助,请大声喊叫!

    【讨论】:

    • 产生异常
    【解决方案2】:

    上面为我返回了一个 IOException 而不是 execute() 返回正确的状态代码。

    使用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
    

    【讨论】:

      猜你喜欢
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 2010-09-22
      • 2016-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多