Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HttpClient似乎正在缓存内容_Java_Multithreading_Http_Get_Httpclient - Fatal编程技术网

Java HttpClient似乎正在缓存内容

Java HttpClient似乎正在缓存内容,java,multithreading,http,get,httpclient,Java,Multithreading,Http,Get,Httpclient,我正在构建一个简单的web scraper,我需要获取相同的页面数百次,页面中有一个动态属性,应该在每次请求时更改。我构建了一个基于多线程HttpClient的类来处理请求,并使用ExecutorService创建一个线程池并运行线程。问题是,动态属性有时不会在每个请求上更改,我最终会在后续的3或4个线程上获得相同的值。我已经读了很多关于HttpClient的书,但我真的不知道这个问题是从哪里来的。这可能是关于缓存的事情,还是类似的事情 更新:以下是每个线程中执行的代码: HttpContext

我正在构建一个简单的web scraper,我需要获取相同的页面数百次,页面中有一个动态属性,应该在每次请求时更改。我构建了一个基于多线程HttpClient的类来处理请求,并使用
ExecutorService
创建一个线程池并运行线程。问题是,动态属性有时不会在每个请求上更改,我最终会在后续的3或4个线程上获得相同的值。我已经读了很多关于HttpClient的书,但我真的不知道这个问题是从哪里来的。这可能是关于缓存的事情,还是类似的事情

更新:以下是每个线程中执行的代码:

HttpContext localContext = new BasicHttpContext();

HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
        HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);

ClientConnectionManager connman = new ThreadSafeClientConnManager();

DefaultHttpClient httpclient = new DefaultHttpClient(connman, params);

HttpHost proxy = new HttpHost(inc_proxy, Integer.valueOf(inc_port));
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
        proxy);

HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");

String iden = null;
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpGet.getParams(),
        timeoutConnection);

try {

    HttpResponse response = httpclient.execute(httpGet, localContext);

    HttpEntity entity = response.getEntity();

    if (entity != null) {

        InputStream instream = entity.getContent();
        String result = convertStreamToString(instream);
        // System.out.printf("Resultado\n %s",result +"\n");
        instream.close();

        iden = StringUtils
                .substringBetween(result,
                        "<input name=\"iden\" value=\"",
                        "\" type=\"hidden\"/>");
        System.out.printf("IDEN:%s\n", iden);
        EntityUtils.consume(entity);
    }

}

catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    System.out.println("Excepção CP");

} catch (IOException e) {
    // TODO Auto-generated catch block
    System.out.println("Excepção IO");
}
HttpContext localContext=new BasicHttpContext();
HttpParams params=新的BasicHttpParams();
HttpProtocolParams.setVersion(params,HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(参数,
HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params,true);
ClientConnectionManager connman=新的ThreadSafeClientConnManager();
DefaultHttpClient httpclient=新的DefaultHttpClient(connman,params);
HttpHost proxy=新的HttpHost(inc_proxy,Integer.valueOf(inc_端口));
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_代理、,
委托书);
HttpGet HttpGet=新的HttpGet(url);
setHeader(“用户代理”,
“Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.1)”;
字符串iden=null;
int timeoutConnection=10000;
HttpConnectionParams.setConnectionTimeout(httpGet.getParams(),
超时连接);
试一试{
HttpResponse response=httpclient.execute(httpGet,localContext);
HttpEntity=response.getEntity();
如果(实体!=null){
InputStream instream=entity.getContent();
字符串结果=convertStreamToString(流内);
//System.out.printf(“Resultado\n%s”,result+“\n”);
流内关闭();
iden=StringUtils
.substringBetween(结果,
"");
System.out.printf(“IDEN:%s\n”,IDEN);
EntityUtils.consume(实体);
}
}
捕获(客户端协议例外e){
//TODO自动生成的捕捉块
System.out.println(“Excepço CP”);
}捕获(IOE异常){
//TODO自动生成的捕捉块
System.out.println(“例外”);
}

一般来说,为了测试HTTP请求是否通过网络发出,您可以使用分析网络流量的“嗅探”工具,例如:

  • Fiddler()-我从这个开始
  • Wireshark()-更低级别
我非常怀疑HttpClient是否正在执行任何类型的缓存(这意味着它需要将页面存储在内存或磁盘中,而不是它的功能之一)

虽然这不是一个答案,但值得深思的是:服务器(或中间的某个代理)是否有可能返回缓存的内容?如果您对同一内容执行多个请求(同时或几乎同时),服务器可能会返回缓存的内容,因为它已确定信息尚未“过期”。事实上,HTTP协议为此类功能提供了缓存指令。以下是一个网站,提供了不同HTTP缓存机制的高级概述:


我希望这能给你一个起点。如果您已经考虑过这些方法,那就太好了。

您可以尝试在每个请求的URL中添加一些唯一的伪参数,以尝试阻止任何基于URL的缓存(在服务器中或在某个地方)。如果缓存不是问题,或者如果服务器足够聪明,可以拒绝具有未知参数的请求,或者如果服务器正在缓存但仅基于其关心的参数,或者如果您选择的参数名称与站点实际使用的参数冲突,则该方法将不起作用

如果这是您正在使用的URL 试用


为每个请求将dummy设置为不同的值。

HTTPClient默认情况下不使用缓存(仅当您使用
DefaultHttpClient
类时)。如果您使用
CachingHttpClient
HttpClient
接口装饰器启用缓存,则会执行此操作:

HttpClient client = new CachingHttpClient(new DefaultHttpClient(), cacheConfiguration);
然后,它分析
是否自
修改,以及
是否不匹配
头,以确定是否执行对远程服务器的请求,或者其结果是否从缓存返回

我怀疑,您的问题是由位于应用程序和远程服务器之间的代理服务器引起的

您可以使用
curl
应用程序轻松测试它;执行一些忽略代理的请求数:

#!/bin/bash

for i in {1..50}
do
  echo "*** Performing request number $i"
  curl -D - http://yourserveraddress.com -o $i -s
done

然后,在所有下载的文件之间执行
diff
。他们都应该有你提到的不同之处。然后,将
-x/--proxy
选项添加到curl,执行此脚本并再次比较文件。如果某些响应与其他响应相同,则可以确定这是代理服务器问题。

可以缓存在服务器端。您可能正在编写线程不安全代码,并且每当下载数据时,旧结果都会被新结果覆盖。没有代码很难判断。我已经用代码更新了问题。我还使用FixedThreadPool来执行线程:
ExecutorService pool=Executors.newFixedThreadPool(10);对于(int i=0;i