`

使用HttpClient登录知乎获取返回页面信息

 
阅读更多

引言

HttpClient是java语言下一个支持http协议的客户端编程工具包,它实现了HTTP协议的所有方法,但是不支持JS渲染。我们在做一些小玩意时,有可能需要登录某些网站获取信息,那么HttpClient就是你的好帮手,废话不多说,进入实战。


一 登录的实际意义

在HTTP横行的今天,我们每天都要登录一些网站,那么登录的意义是什么呢?首先要对cookie要有一定了解。cookie是存放在本地的一些小文件,它由服务器发送命令,浏览器在本地读写。当访问某些网站的时候,浏览器会检查是否有所浏览网站的cookie信息,如果有则在发送访问请求的时候携带上这些内容,服务器可以读取到浏览器发送请求中的cookie信息,在回应请求时可以再写cookie信息。cookie信息包括键值,内容,过期时间,所属网站。

说到这里cookie差不多讲完了,那么登录到底是怎么回事?登录就是服务器向你的浏览器写cookie,如果仅仅是在你的计算机上写cookie,那么别有用心的人伪造一个cookie也有机会登录网站,所以服务器会在内存中保留一份相同的信息,这个过程叫做会话。如果你在网站点击退出按钮,服务器会把内存中的cookie清除掉,同时清除浏览器中有关登录的cookie。知道了这些,我们就可以上手了。


二 找到登录关键cookie

这里我们可以用wireshark来抓包分析一下。打开知乎首页,打开wireshark,开始监听端口,输入用户名和密码,点击登录,查看wireshark抓到的包。截图如下:

第一张图是本地post提交数据。

第二张图是提交的信息,包括_xsrf,password,remember_me,email,注意,提交的信息中包括cookie,_xsrf可以从知乎首页中获取。

第三张图是服务器返回的信息,注意它的状态是200,说明是成功的。

第四章图是服务器返回的数据,注意它有三条cookie设置,以及带有一个登录成功与否的信息。

通过上边的步骤我们能知道什么呢?首先,发送登录请求的时候带有的cookie,以及post数据的格式,其次我们能拿到登录用cookie信息(第四张图)。

三 使用HttpClient构造登录信息

HttpClient是怎样模拟浏览器的呢?首先需要建立一个HttpClient,这个HttpClient是用来模拟一个浏览器。其次构造一个post请求,添加post数据信息以及cookie。详细代码如下:

import org.apache.http.*;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Lookup;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.cookie.DefaultCookieSpecProvider;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
 
/**
 * Created by gavin on 15-7-23.
 */
public class HttpClientTest {
 
    public static void main(String[] args)
    {
        //创建一个HttpClient
        RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
        try {
            //创建一个get请求用来接收_xsrf信息
        HttpGet get = new HttpGet("http://www.zhihu.com/");
            //获取_xsrf
            CloseableHttpResponse response = httpClient.execute(get,context);
            setCookie(response);
            String responseHtml = EntityUtils.toString(response.getEntity());
            String xsrfValue = responseHtml.split("<input type=\"hidden\" name=\"_xsrf\" value=\"")[1].split("\"/>")[0];
            System.out.println("xsrfValue:" + xsrfValue);
            response.close();
             
            //构造post数据
            List<NameValuePair> valuePairs = new LinkedList<NameValuePair>();
            valuePairs.add(new BasicNameValuePair("_xsrf", xsrfValue));
            valuePairs.add(new BasicNameValuePair("email", "xxxx@xxx.com"));
            valuePairs.add(new BasicNameValuePair("password", "xxxxx"));
            valuePairs.add(new BasicNameValuePair("remember_me", "true"));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8);
             
            //创建一个post请求
            HttpPost post = new HttpPost("http://www.zhihu.com/login/email");
            post.setHeader("Cookie", " cap_id=\"YjA5MjE0YzYyNGQ2NDY5NWJhMmFhN2YyY2EwODIwZjQ=|1437610072|e7cc307c0d2fe2ee84fd3ceb7f83d298156e37e0\"; ");
 
            //注入post数据
            post.setEntity(entity);
            HttpResponse httpResponse = httpClient.execute(post);
            //打印登录是否成功信息
            printResponse(httpResponse);
 
            //构造一个get请求,用来测试登录cookie是否拿到
            HttpGet g = new HttpGet("http://www.zhihu.com/question/following");
            //得到post请求返回的cookie信息
            String c = setCookie(httpResponse);
            //将cookie注入到get请求头当中
            g.setHeader("Cookie",c);
            CloseableHttpResponse r = httpClient.execute(g);
            String content = EntityUtils.toString(r.getEntity());
            System.out.println(content);
            r.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    public static void printResponse(HttpResponse httpResponse)
            throws ParseException, IOException {
        // 获取响应消息实体
        HttpEntity entity = httpResponse.getEntity();
        // 响应状态
        System.out.println("status:" + httpResponse.getStatusLine());
        System.out.println("headers:");
        HeaderIterator iterator = httpResponse.headerIterator();
        while (iterator.hasNext()) {
            System.out.println("\t" + iterator.next());
        }
        // 判断响应实体是否为空
        if (entity != null) {
            String responseString = EntityUtils.toString(entity);
            System.out.println("response length:" + responseString.length());
            System.out.println("response content:"
                    + responseString.replace("\r\n", ""));
        }
    }
 
    public static Map<String,String> cookieMap = new HashMap<String, String>(64);
    //从响应信息中获取cookie
    public static String setCookie(HttpResponse httpResponse)
    {
        System.out.println("----setCookieStore");
        Header headers[] = httpResponse.getHeaders("Set-Cookie");
        if (headers == null || headers.length==0)
        {
            System.out.println("----there are no cookies");
            return null;
        }
        String cookie = "";
        for (int i = 0; i < headers.length; i++) {
            cookie += headers[i].getValue();
            if(i != headers.length-1)
            {
                cookie += ";";
            }
        }
 
        String cookies[] = cookie.split(";");
        for (String c : cookies)
        {
            c = c.trim();
            if(cookieMap.containsKey(c.split("=")[0]))
            {
                cookieMap.remove(c.split("=")[0]);
            }
            cookieMap.put(c.split("=")[0], c.split("=").length == 1 ? "":(c.split("=").length ==2?c.split("=")[1]:c.split("=",2)[1]));
        }
        System.out.println("----setCookieStore success");
        String cookiesTmp = "";
        for (String key :cookieMap.keySet())
        {
            cookiesTmp +=key+"="+cookieMap.get(key)+";";
        }
 
        return cookiesTmp.substring(0,cookiesTmp.length()-2);
    }
}


代码的流程是:

  1. 从知乎首页获取xsrf信息。

  2. post请求当中需要cookie信息,但是我们第一步中没有得到cookie,请在浏览器中自行找到cookie添加进去,上边的cookie是我找到的。

  3. 提交post请求,得到登录用cookie

  4. 随便找一个需要登录的子页面,将得到的cookie写入到请求头中,提交请求,查看是否已经登录成功


四 结果验证

第一张图显示得到cookie并登录成功

第二张图显示已经进入需要登录的界面


总结

当我们需要登录一个界面获取信息的时候,我们要知道登录实际上做了什么,那就是读写cookie,post数据。

获取cookie时,需要从响应头中获取,当服务器发来新的cookie信息时需要及时写入。

当我们能登录一个网站的时候,如何对其内容进行操作,这里推荐jsoup,良心库,仿jquery操作模式。

摘自开源中国社区:http://my.oschina.net/jiangmitiao/blog/483092

分享到:
评论

相关推荐

    使用HttpClient登录网易邮箱

    然后可以读取响应体,获取服务器返回的信息。对于登录操作,可能需要解析返回的Cookie,以便后续的会话保持。 8. **异常处理**:捕获并处理可能出现的网络异常、解析异常等。 9. **关闭连接**:记得在操作完成后...

    java httpclient 模拟登录

    在"java httpclient 模拟登录"这个场景下,我们通常会用到HttpClient来模拟用户登录网站的过程,获取登录后的session信息,以便后续能够访问登录后才能看到的页面内容。以下将详细介绍如何使用Java HttpClient进行...

    httpClient和htmlparse获取网页数据使用jar

    在IT行业中,获取网页数据是常见的任务之一,用于数据分析、信息抓取或自动化测试等场景。HttpClient和HtmlParser是两个非常实用的Java库,分别用于处理HTTP通信和解析HTML内容。下面将详细介绍这两个库以及如何结合...

    HttpClient 登录163邮箱

    在登录过程中,可能需要解析返回的HTML页面以获取验证码或提取其他动态信息。这里使用了`nekohtml.jar`,这是一个用于解析HTML和XML文档的库,可以帮助解析和构建DOM树。 6. **Cookie管理** HttpClient通过`...

    HttpClient获取OAuth2.0中的code

    通过httpclient post去获取,response返回码是302,返回的code放在header的Location中。 请求的时候client_id,response_type,redirect_uri,state拼接在url后面,account和password放在body表单(x-...

    使用HttpClient获取网页html源代码.zip

    在这个名为"使用HttpClient获取网页html源代码.zip"的压缩包中,包含了一个简单的示例项目——WebDataShow,用于演示如何使用HttpClient获取网页HTML。 首先,我们需要导入Apache HttpClient库。在Android Studio中...

    httpClient 调用远程接口 获取数据到本地文件夹

    在这个场景中,我们使用HttpClient来调用远程接口,从电信公司的网站获取可用的新手机号码信息,并将这些数据存储到本地文件中。以下是对这个过程的详细解释: 1. **HttpClient的基本使用**: HttpClient提供了一...

    httpclient 获取技术博客列表

    例如,开发者可能首先使用HttpClient向这些页面发送请求,然后解析返回的HTML,提取出博客列表、文章标题、链接等信息。在实际应用中,这可能涉及DOM解析、正则表达式匹配或者使用像Jsoup这样的库来解析HTML内容。 ...

    使用HttpClient发送POST请求,并获取响应内容(附详细步骤).txt

    ### 使用HttpClient发送POST请求,并获取响应内容 #### 一、简介 在现代软件开发中,尤其是在Web应用领域,客户端与服务器之间的通信是非常重要的环节。Java作为一种广泛应用的编程语言,提供了多种方式来实现这一...

    Java爬虫Jsoup+httpclient获取动态生成的数据

    通过分析这些请求,开发者可以找到数据接口,并使用HttpClient来模拟这些请求,获取到动态加载的数据。 在本例中,我们通过Jsoup获取到了京东商品页面的静态HTML代码,但价格信息并未包含在内。通过分析页面源码...

    httpclient如何保持session会话模拟登录后的操作

    4. **执行登录请求**: 使用HttpClient执行登录请求,获取响应。 ```java CloseableHttpResponse loginResponse = httpClient.execute(httpPost); ``` 5. **处理登录响应**: 检查登录是否成功。通常,成功登录后...

    java使用HttpClient通过url下载文件到本地

    - **执行请求**:使用HttpClient的`execute()`方法发送请求,并获取`HttpResponse`对象。 - **处理响应**:检查响应状态码,通常200表示成功。然后,通过`EntityUtils`类的`toString()`或`getContent()`方法获取...

    HttpClient登录

    在文件名列表中的"photo163"可能是网易相册的某种标识,如果这是登录后访问的资源,你可能需要在登录成功后,使用相同的`HttpClient`实例来发送新的GET请求获取资源。 总的来说,HttpClient提供了一套强大的工具来...

    HttpClient网络获取图片

    从网络获取数据和图片,用gson解析并用listview展示

    知乎爬虫(知乎网站爬取工具,爬取知乎网页内容)

    知乎网站的动态加载特性增加了爬虫的复杂性,因为许多内容在页面加载后通过Ajax技术异步获取。因此,知乎爬虫可能需要处理JavaScript执行,可能借助于Headless浏览器如Puppeteer(在Node.js环境中)或Selenium(支持...

    通过HTTPClient获取网络资源

    本篇文章将深入探讨如何使用`HttpClient`来获取网络资源,以及处理返回的XML数据。 首先,我们需要了解`HttpClient`的基本用法。在Java中,创建一个`HttpClient`实例是获取网络资源的第一步。`HttpClient`提供了...

    httpclient方式调用url

    4. **执行请求**:使用HttpClient实例执行请求,并获取HttpResponse对象: ```java HttpResponse response = httpClient.execute(httpGet); ``` 5. **处理响应**:从HttpResponse对象中读取响应状态码和数据。...

    HttpClient以及获取页面内容应用

    HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。 下载地址:  http://hc.apache.org/downloads.cgi 1.2特性 1. 基于标准、纯净的java语言。...

    使用httpclient4登录blog.com

    5. **执行请求**:使用`HttpClient`执行POST请求,并获取响应。 ```java CloseableHttpResponse response = httpClient.execute(httpPost); ``` 6. **处理响应**:检查响应状态码(如200表示成功),读取响应实体...

Global site tag (gtag.js) - Google Analytics