文档章节

一种解决HTTP抓取网页超时设置无效的方法

杨尚川
 杨尚川
发布于 2017/06/17 20:27
字数 471
阅读 257
收藏 1

今天发现superword在获取单词定义的时候,对于不常见单词,网页打开很慢,超过10秒,经检查,发现是利用Jsoup来抓取单词定义的时候,设置的超时3秒无效,_getContent方法的执行时间超过10秒,代码如下:

    public static String getContent(String url) {
        String html = _getContent(url);
        int times = 0;
        while(StringUtils.isNotBlank(html) && html.contains("非常抱歉,来自您ip的请求异常频繁")){
            //使用新的IP地址
            ProxyIp.toNewIp();
            html = _getContent(url);
            if(++times > 2){
                break;
            }
        }
        return html;
    }

    private static String _getContent(String url) {
        Connection conn = Jsoup.connect(url)
                .header("Accept", ACCEPT)
                .header("Accept-Encoding", ENCODING)
                .header("Accept-Language", LANGUAGE)
                .header("Connection", CONNECTION)
                .header("Referer", REFERER)
                .header("Host", HOST)
                .header("User-Agent", USER_AGENT)
                .timeout(3000)
                .ignoreContentType(true);
        String html = "";
        try {
            html = conn.post().html();
            html = html.replaceAll("[\n\r]", "");
        }catch (Exception e){
            LOGGER.error("获取URL:" + url + "页面出错", e);
        }
        return html;
    }

所以想了一个办法来解决这个问题,核心思想是主线程启动一个子线程来抓取单词定义,然后主线程休眠指定的超时时间,当超时时间过去后,从子线程获取抓取结果,这个时候如果子线程抓取还未完成,则主线程返回空的单词定义,代码如下:

    public static String getContent(String url) {
        long start = System.currentTimeMillis();
        String html = _getContent(url, 1000);
        LOGGER.info("获取拼音耗时: {}", TimeUtils.getTimeDes(System.currentTimeMillis()-start));
        int times = 0;
        while(StringUtils.isNotBlank(html) && html.contains("非常抱歉,来自您ip的请求异常频繁")){
            //使用新的IP地址
            ProxyIp.toNewIp();
            html = _getContent(url);
            if(++times > 2){
                break;
            }
        }
        return html;
    }

    private static String _getContent(String url, int timeout) {
        Future<String> future = ThreadPool.EXECUTOR_SERVICE.submit(()->_getContent(url));
        try {
            Thread.sleep(timeout);
            return future.get(1, TimeUnit.NANOSECONDS);
        } catch (Throwable e) {
            LOGGER.error("获取网页异常", e);
        }
        return "";
    }

    private static String _getContent(String url) {
        Connection conn = Jsoup.connect(url)
                .header("Accept", ACCEPT)
                .header("Accept-Encoding", ENCODING)
                .header("Accept-Language", LANGUAGE)
                .header("Connection", CONNECTION)
                .header("Referer", REFERER)
                .header("Host", HOST)
                .header("User-Agent", USER_AGENT)
                .timeout(1000)
                .ignoreContentType(true);
        String html = "";
        try {
            html = conn.post().html();
            html = html.replaceAll("[\n\r]", "");
        }catch (Exception e){
            LOGGER.error("获取URL:" + url + "页面出错", e);
        }
        return html;
    }

详细代码地址:

https://github.com/ysc/superword/commit/e4bc3c4197af95a8d7519856c89d592515a1c18f

 

 

 

© 著作权归作者所有

杨尚川

杨尚川

粉丝 1103
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
服务器返回状态码大全

服务器返回的各种状态码到底表示什么意思呢,哪些说明没有问题,哪些返回状态是出问题了,这个返回状态码表示的是什么意思,下面是服务器各种返回状态码的意义: 100(继续) 请求者应当继续...

qq512430
2017/03/31
0
0
网站日志HTTP返回代码解析:201 304 404 500【知识普及】

在网站日志中,我们经常会看到很多返回的http代码,如201、304、404、500等等。可是这些具体的返回的HTTP代码究竟什么含义呢,在此做一下知识普及吧,记不住不要紧,到时候看看就行了,但最主...

土鳖的弟弟
2014/04/21
164
0
常见HTTP状态码(200,304,404等)

一些常见的状态码为: · 200 – 服务器成功返回网页 · 404 – 请求的网页不存在 · 503 – 服务器超时 下面提供 HTTP 状态码的完整列表。点击链接可了解详情。您也可以访问 HTTP 状态码上的...

梦梦阁
2018/10/29
18
0
73.HTTP请求返回的数字代表的具体含义

一些常见的状态码为:   200 - 服务器成功返回网页   404 - 请求的网页不存在   503 - 服务器超时   下面提供 HTTP 状态码的完整列表。点击链接可了解详情。您也可以访问 HTTP 状态码...

Lucky_Me
2017/12/27
14
0
301、404、200、304、500HTTP状态

一些常见的状态码为:   200 - 服务器成功返回网页   404 - 请求的网页不存在   503 - 服务器超时   下面提供 HTTP 状态码的完整列表。点击链接可了解详情。您也可以访问 HTTP 状态码...

蓓蕾心晴
2017/05/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

最简单的获取相机拍照的图片

  import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import andr......

MrLins
31分钟前
4
0
说好不哭!数据可视化深度干货,前端开发下一个涨薪点在这里~

随着互联网在各行各业的影响不断深入,数据规模越来越大,各企业也越来越重视数据的价值。作为一家专业的数据智能公司,个推从消息推送服务起家,经过多年的持续耕耘,积累沉淀了海量数据,在...

个推
33分钟前
7
0
第三方支付-返回与回调注意事项

不管是支付宝,微信,还是其它第三方支付,第四方支付,支付机构服务商只要涉及到钱的交易都要进行如下校验,全部成功了才视为成功订单 1.http请求是否成功 2.校验商户号 3.校验订单号及状态...

Shingfi
35分钟前
4
0
简述Java内存分配和回收策略以及Minor GC 和 Major GC(Full GC)

内存分配: 1. 栈区:栈可分为Java虚拟机和本地方法栈 2. 堆区:堆被所有线程共享,在虚拟机启动时创建,是唯一的目的是存放对象实例,是gc的主要区域。通常可分为两个区块年轻代和年老代。更...

DustinChan
41分钟前
6
0
Excel插入批注:可在批注插入文字、形状、图片

1.批注一直显示:审阅选项卡-------->勾选显示批注选项: 2.插入批注快捷键:Shift+F2 组合键 3.在批注中插入图片:鼠标右键点击批注框的小圆点【重点不可以在批注文本框内点击】----->调出批...

东方墨天
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部