zoukankan      html  css  js  c++  java
  • HttpClient4.0&HtmlCleaner用法

    **************************HttpClient4.0用法***************************** 
    1、初始化HttpParams,设置组件参数 
            //HttpParams接口代表一个不可改变值的集合,定义一个组件运行时行为。代表一个对象集合,该集合是一个键到值的映射。 
    //HttpParams作用是定义其他组件的行为,一般每个复杂的组件都有它自己的HttpParams对象。 
      
       HttpParams params = new BasicHttpParams(); 

       // HTTP 协议的版本,1.1/1.0/0.9 
       HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
       HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1"); 
       HttpProtocolParams.setUseExpectContinue(params, true); 
       
       ConnManagerParams.setMaxTotalConnections(params, maxconnections); // 设置最大连接数maxconnections); 
       ConnManagerParams.setTimeout(params, timeout*1000);  // 设置超时时间 timeout 秒 
    2、初始化SchemeRegistry,设置访问协议 
       (Scheme 类代表了一个协议模式,比如“http”或“https”,同时包含一些协议属性(如默认端口),用来为给定协议创建java.net.Socket实例的套接字实例。SchemeRegistry类用来维持一组Scheme,当去通过请求URI建立连接时,HttpClient可以从中选择:)
             //Scheme类表示一个协议方案,例如"http"或者"https"和包含许多的协议属性, 
             //例如缺省的端口和socket工厂常用于为指定的协议创建java.net.Socket实例,SchemeRegistry类被用来维护一个Schemes的集合 
       SchemeRegistry schemeRegistry = new SchemeRegistry(); 
       schemeRegistry.register(new Scheme("http", PlainSocketFactory 
    .getSocketFactory(), 80)); 
       schemeRegistry.register(new Scheme("https", SSLSocketFactory 
    .getSocketFactory(), 443)); 
    3、初始化httpclient会话连接管理器 
             //HTTP连接是复杂、有状态的,非线程安全的对象需要适当的管理正确的功能。HTTP连接每次仅被一个执行的线程使用, 
             //HttpClient利用一个特殊的实体管理访问HTTP连接,称为HTTP连接管理器,由ClientConnectionManager接口表示。 
             //HTTP连接管理器的充当一个新的HTTP连接工厂,管理持续的连接和同步的访问持续的连接,确保每次只有一个线程能访问连接。 
       ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params, 
    schemeRegistry); 
    4、初始化httpClient并加入会话连接管理器,此步很重要,对于使用httpclient多线程并发访问服务系统很有用 
             //HttpClient最重要的功能是执行HTTP方法。执行一个HTTP方法涉及一个或多个HTTP请求/ HTTP响应信息交流, 
             //通常是由HttpClient内部处理。用户提供一个请求对象,HttpClient发送请求到目标服务器, 
             //希望服务器返回一个相应的响应对象,或者抛出一个异常(如果执行失败)。 
       HttpClient httpClient = new DefaultHttpClient(connectionManager, params); 
    5、定义HttpHost 
             // HttpHost代表访问的主机 
             String sHost = "www.hao123.com"; //访问服务器的主网址 
             httpHost = new HttpHost(sHost); 

    6、执行get请求 
    6.1 先定义方法getResponseContent,用来根据指定系统编码获取响应主体内容,很有用的方法 
             public String getResponseContent(HttpEntity responseEntity) 
    throws Exception { 
    byte[] bytes = EntityUtils.toByteArray(responseEntity); 
                    String sCharSet="GB2312";       //这里可以定义你指定的编码,中文网站编码一般为GB2312 
    return new String(bytes, sCharSet); 

             
    6.2 执行get请求,获取响应的html内容 
             String sURL="/abc/index.html"; //定义你需要访问的网址后面的路径       
             HttpGet httpGet = new HttpGet(sURL);//定义get请求 
             HttpResponse httpResponse = httpClient.execute(httpHost, httpGet); //使用httpclient执行get请求并返回响应  访问的网址为 www.hao123.com/abc/index.html 
             // 2 获取响应 
    HttpEntity responseEntity = httpResponse.getEntity(); 
    String sReturnHtml = getResponseContent(responseEntity);//得到get请求返回的html页面,然后就做你想做的东西了 
             //比如解析html页面,得到你想得到的东西 
             
             httpGet.abort();//释放连接资源,很重要,不能缺少 
             
    7、执行post请求 
    7.1初始化httppost 
       String sURL="/abc/index.html"; 
       HttpPost httpPost = new HttpPost(sURL); 
    7.2设置Post请求参数NameValuePair 
       List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 
       nvps.add(new BasicNameValuePair("name", "testname")); 
       nvps.add(new BasicNameValuePair("password", "testpassword"));  
    7.3把请求参数按指定编码设置到httppost中,设置httppost请求头内容,可解决中文乱码问题,非常重要 
       String sCharSet="GB2312"; 
       httpPost.setEntity(new UrlEncodedFormEntity(nvps, sCharSet)); 
       // ---begin解决中文乱码问题 
       httpPost.addHeader("Content-Type","application/x-www-form-urlencoded"); 
       httpPost.addHeader("Accept-Language", "zh-cn"); 
       httpPost.addHeader("Accept-Encoding", "gzip, deflate"); 
       // ---end 
    7.4执行post请求,得到响应做其他操作 
       
       HttpResponse httpResponse = httpClient.execute(httpHost, httpPost); 
       HttpEntity responseEntity = httpResponse.getEntity(); 
       String sHtml = getResponseContent(responseEntity); 
       
       httpPost.abort();//释放连接资源 


       connectionManager.shutdown();//关闭连接管理器 
       
    总结:使用httpclient访问需要用户登录的网站做相关操作,需要从登录、判断登录成功、做你想要的事情、退出 一连贯动作 
          因为大部分网站服务器是根据用户访问的会话session来判断一个用户是否在线的才能做相关操作,所以退出动作不实现的话, 
          在httpclient多线程并发访问网站的时候,服务器会出现数据混乱等想不到的状况。 
          判断登录是否成功这个问题,我的解决方案是获取登录POST请求返回响应,然后从响应中获取重定向地址。 
          一般的WEB服务系统设计时,登录成功和失败返回的重定向地址是不一致的。所以我只要判断返回的重定向地址是否是成功的就可以了。 
             /**** 
    * 获取响应头重定向地址 
    * @param response 
    * @return 
    */ 
    public String getRedirectLocation(HttpResponse response) { 
    String sReturn; 
    Header locationHeader = response.getFirstHeader("Location"); 
    if (locationHeader == null) { 
    sReturn = ""; 
    } else { 
    sReturn = locationHeader.getValue(); 

    if (log.isDebugEnabled()) { 
    log.debug("##########重定向URL:" + sReturn); 

    return sReturn; 

           
          POST请求中文乱码问题在网上搜索了很多方案,都无法解决, 
          后来我用HttpAnalyzer分析用浏览器访问正常情况时,发现请求头中包含了三个参数 "Content-Type"、"Accept-Language"、 
          "Accept-Encoding",在httppost中添加请求头加入这几个参数后,发现问题解决了。 
         
          因为和4.0之前的版本比较,发生了很多变化,所以上面的总结对之前的版本不实用。 
          需要的jar包:      
                        apache-mime4j-0.6.jar 
                        commons-codec-1.3.jar 
                        commons-logging-1.1.1.jar 
                        httpclient-4.0.3.jar 
                        httpcore-4.0.1.jar 
                        httpmime-4.0.3.jar 


    ************************************************************************** 

    *******************************htmlcleaner用法**************************** 
             String sHtml="";//网页内容 
             HtmlCleaner cleaner = new HtmlCleaner(); 
             TagNode rootNode = cleaner.clean(sHtml); 
             String XPath="//body//form//input";//用XPath语法来表示具体位置的路径 
             Object[] subNodes = rootNode.evaluateXPath(sXPath); 
    for (int i = 0; i < subNodes.length; i++) { 
    TagNode inputNode = (TagNode) subNodes[i]; 
    String sName = inputNode.getAttributeByName("name"); 
    String sValue = inputNode.getAttributeByName("value");

             需要jar包: 
                      htmlcleaner-2.2.jar 
                      
    ************************************************************************** 
  • 相关阅读:
    C++ 运行时类型识别 知道实例父类类型,显示出子类类型
    C++里面方便的打印日志到文件
    vs2015上配置Armadillo+openBlas
    opencl 在vs2015上遇见的问题
    Lucene子项目------------------Solr遇到的问题
    [LeetCode]Course Schedule
    [LeetCode]Minimum Size Subarray Sum
    [LeetCode]Reverse Linked List
    [LeetCode]Isomorphic Strings
    [LeetCode]Ugly Number
  • 原文地址:https://www.cnblogs.com/wlh652475101/p/3467658.html
Copyright © 2011-2022 走看看