java - HttpClient 不保持登录状态

标签 java android web-scraping httpclient

我正在尝试使用 HttpClient 登录后浏览网站。

我首先定义 HttpClient 的实例以及 cookie 存储:

public HttpClient httpclient = new DefaultHttpClient();
public CookieStore cookieStore = new BasicCookieStore();
public HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

在一个(android)BackgroundTask中,我成功登录网站。

HttpPost httppost = new HttpPost("http://www.deeproute.com/deeproute/default.asp");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("cookieexists","false"));
nameValuePairs.add(new BasicNameValuePair("name", mUser));
nameValuePairs.add(new BasicNameValuePair("password", mPassword));
nameValuePairs.add(new BasicNameValuePair("subbera", "Login"));

httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
res = httpclient.execute(httppost, localContext);

此后,在另一个BackgroundTask中,我尝试连接到同一网站上的不同页面:

HttpGet rosterGet = new HttpGet("http://deeproute.com/deeproute/?sel=rosterlook&myleagueno=6&myteamno=12");
res = httpclient.execute(rosterGet, localContext);

但是,当我连接到此页面时,我不再登录。我查看了一下,成功登录后的 cookie 仍然存在,所以我不知所措。

编辑:郑重声明,该网站在普通浏览器中完全正常运行。

<小时/>

编辑2:为了响应下面Aaron的回答,cookie似乎正在保存,因为如果在第一个请求之后,我会这样做:

List<Cookie> cookies = cookieStore.getCookies();
    int cookieSize = cookies.size();

    for (int i = 0; i < cookieSize; i++) {
        Log.v(TAG, "Cookie " + i + "name: "
                                + cookies.get(i).getName());
        Log.v(TAG, "Cookie " + i + "value: "
                                + cookies.get(i).getValue());
    }

我取回了四个 cookie,其中一个存储了我的用户名。如果我在第二次请求后做同样的事情,我实际上会返回 6 个 cookie,因为显然它给了我一个新的 session ID。这似乎是问题的根源,但我不知道如何解决它。

第一次请求后,这是我的 session ID cookie:

name: ASPSESSIONIDSCSCSBCS
value: GBAJALJBOGKBFLAELPNKEDOE

在第二个请求之后,我有两个 session ID cookie:

name: ASPSESSIONIDSCSCSBCS
value: GBAJALJBOGKBFLAELPNKEDOE

name: ASPSESSIONIDSCSCSBCS
value: MBAJALJBDBOKPEHNCDDFOCBC

最佳答案

我也遇到了同样的问题。我实现了 cookie,但是它仍然没有保持登录状态。我终于让它工作了,所以我发布这段代码,希望可以帮助其他遇到同样问题的人。

以下是 Apache 中有关如何登录和检索所有 cookie 的示例:https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientFormLogin.java

您还可以在此处查看 Apache 的 HttpClient 关于“HTTP 状态管理”的文档:https://hc.apache.org/httpcomponents-client-ga/tutorial/html/statemgmt.html

以下是我的登录功能的实现方式:

  1. 使用 CredentialsProvider 设置代理
  2. 使用BasicCookieStore设置cookie
  3. 使用 CloseableHttpClient 构建自定义 HttpClient
  4. 设置POST 请求:目标、主机、参数、路径
  5. 执行/login.html发送POST请求以登录。
  6. /user 执行 GET 请求以查看我们是否正确登录
  7. 打印响应的状态代码

    //////// SETUP
    //Setup Proxy (If needed)
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope("proxy.mycompany", 8080),
                new UsernamePasswordCredentials("my_username", "my_password"));
    //Setup Cookies
        BasicCookieStore cookieStore = new BasicCookieStore();
    
    //Build HttpClient
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .setDefaultCookieStore(cookieStore)
                .build();
        HttpHost target = new HttpHost("www.mycompany.com", 80, "http");
        HttpHost proxy = new HttpHost("proxy.mycompany", 8080);
        RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .build();
    try {
    //////// LOGIN REQUEST, POST TO /login.html
    //Start POST Request
        HttpPost httppost = new HttpPost('/login.html');
    //Add parameters to POST Request
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();   
        nameValuePairs.add(new BasicNameValuePair('username','my_username'));  
        nameValuePairs.add(new BasicNameValuePair('password','my_password'));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    //Set Config for POST Request
        httppost.setConfig(config);
    //Execute POST Request
        httpresponse = httpclient.execute(target, httppost);
    //Print Response Code
        try {
           System.out.println("Status Code: "+httpresponse.getStatusLine().getStatusCode());
        } finally {
    //Close HTTP Reponse (must be in a 'finally' block)
            httpresponse.close();
        }
    
    //////// CHECK LOGIN STATUS, GET TO /user
    //Start GET Request
        HttpGet httpget = new HttpGet('/user');
    //Set Config for GET Request
        httpget.setConfig(config);
    //Execute GET Request
        httpresponse = httpclient.execute(target, httpget);
    //Print Response Code
        try {
           System.out.println("Status Code: "+httpresponse.getStatusLine().getStatusCode());
        } finally {
    //Close HTTP Reponse (must be in a 'finally' block)
            httpresponse.close();
        }
    } finally {
        httpclient.close();
    }
    

关于java - HttpClient 不保持登录状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16245577/

相关文章:

python - 为什么我会收到 ElementClickInterceptedException 错误?

Java Applet 无法正确显示

java.lang.NoSuchMethodError : cucumber. 运行时.Runtime

java - 为什么这段代码中有Unhandled Exception?

Android GMS 库抛出 IllegalArgumentException : Unexpected number of IObjectWrapper declared fields: 3

android - 如何使用 firebase ML Kit 识别条形码?

android - 有没有办法通过 WebRTC 在 Android 中捕获/共享自己的应用程序屏幕?

python - Scrapy - 发送新请求/使用回调

java - 获取 SimpleDateFormat 的模式

python-3.x - BeautifulSoup 和 pd.read_html - 如何将链接保存到最终数据框中的单独列中?