成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

HttpClient4.4 登錄知乎(詳細(xì)過程)

lucas / 369人閱讀

摘要:打開知乎首頁,打開,開始監(jiān)聽端口,輸入用戶名和密碼,點(diǎn)擊登錄,查看抓到的包。第二張圖是提交的信息,包括,,,,注意,提交的信息中包括,可以從知乎首頁中獲取。

引言

HttpClient是java語言下一個(gè)支持http協(xié)議的客戶端編程工具包,它實(shí)現(xiàn)了HTTP協(xié)議的所有方法,但是不支持JS渲染。我們?cè)谧鲆恍┬⊥嬉鈺r(shí),有可能需要登錄某些網(wǎng)站獲取信息,那么HttpClient就是你的好幫手,廢話不多說,進(jìn)入實(shí)戰(zhàn)。

一 登錄的實(shí)際意義

在HTTP橫行的今天,我們每天都要登錄一些網(wǎng)站,那么登錄的意義是什么呢?首先要對(duì)cookie要有一定了解。cookie是存放在本地的一些小文件,它由服務(wù)器發(fā)送命令,瀏覽器在本地讀寫。當(dāng)訪問某些網(wǎng)站的時(shí)候,瀏覽器會(huì)檢查是否有所瀏覽網(wǎng)站的cookie信息,如果有則在發(fā)送訪問請(qǐng)求的時(shí)候攜帶上這些內(nèi)容,服務(wù)器可以讀取到瀏覽器發(fā)送請(qǐng)求中的cookie信息,在回應(yīng)請(qǐng)求時(shí)可以再寫cookie信息。cookie信息包括鍵值,內(nèi)容,過期時(shí)間,所屬網(wǎng)站。

說到這里cookie差不多講完了,那么登錄到底是怎么回事?登錄就是服務(wù)器向你的瀏覽器寫cookie,如果僅僅是在你的計(jì)算機(jī)上寫cookie,那么別有用心的人偽造一個(gè)cookie也有機(jī)會(huì)登錄網(wǎng)站,所以服務(wù)器會(huì)在內(nèi)存中保留一份相同的信息,這個(gè)過程叫做session會(huì)話。如果你在網(wǎng)站點(diǎn)擊退出按鈕,服務(wù)器會(huì)把內(nèi)存中的cookie清除掉,同時(shí)清除瀏覽器中有關(guān)登錄的cookie。知道了這些,我們就可以上手了。

二 找到登錄關(guān)鍵cookie

這里我們可以用wireshark來抓包分析一下。打開知乎首頁,打開wireshark,開始監(jiān)聽端口,輸入用戶名和密碼,點(diǎn)擊登錄,查看wireshark抓到的包。截圖如下:

第一張圖是瀏覽器post提交數(shù)據(jù)。

第二張圖是提交的信息,包括_xsrf,password,remember_me,email,注意,提交的信息中包括cookie,_xsrf可以從知乎首頁中獲取。

第三張圖是服務(wù)器返回的信息,注意它的狀態(tài)是200,說明是成功的。

第四章圖是服務(wù)器返回的數(shù)據(jù),注意它有三條cookie設(shè)置,以及帶有一個(gè)登錄成功與否的信息。

通過上邊的步驟我們能知道什么呢?首先,發(fā)送登錄請(qǐng)求的時(shí)候帶有的cookie,以及post數(shù)據(jù)的格式,其次我們能拿到登錄用cookie信息(第四張圖)。

三 使用HttpClient構(gòu)造登錄信息

HttpClient是怎樣模擬瀏覽器的呢?首先需要建立一個(gè)HttpClient,這個(gè)HttpClient是用來模擬一個(gè)瀏覽器。其次構(gòu)造一個(gè)post請(qǐng)求,添加post數(shù)據(jù)信息以及cookie。詳細(xì)代碼如下:

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)
    {
        //創(chuàng)建一個(gè)HttpClient
        RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
        try {
            //創(chuàng)建一個(gè)get請(qǐng)求用來接收_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("")[0];
            System.out.println("xsrfValue:" + xsrfValue);
            response.close();
             
            //構(gòu)造post數(shù)據(jù)
            List valuePairs = new LinkedList();
            valuePairs.add(new BasicNameValuePair("_xsrf", xsrfValue));
            valuePairs.add(new BasicNameValuePair("email", "[email protected]"));
            valuePairs.add(new BasicNameValuePair("password", "xxxxx"));
            valuePairs.add(new BasicNameValuePair("remember_me", "true"));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8);
             
            //創(chuàng)建一個(gè)post請(qǐng)求
            HttpPost post = new HttpPost("http://www.zhihu.com/login/email");
            post.setHeader("Cookie", " cap_id="YjA5MjE0YzYyNGQ2NDY5NWJhMmFhN2YyY2EwODIwZjQ=|1437610072|e7cc307c0d2fe2ee84fd3ceb7f83d298156e37e0"; ");
 
            //注入post數(shù)據(jù)
            post.setEntity(entity);
            HttpResponse httpResponse = httpClient.execute(post);
            //打印登錄是否成功信息
            printResponse(httpResponse);
 
            //構(gòu)造一個(gè)get請(qǐng)求,用來測(cè)試登錄cookie是否拿到
            HttpGet g = new HttpGet("http://www.zhihu.com/question/following");
            //得到post請(qǐng)求返回的cookie信息
            String c = setCookie(httpResponse);
            //將cookie注入到get請(qǐng)求頭當(dāng)中
            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 {
        // 獲取響應(yīng)消息實(shí)體
        HttpEntity entity = httpResponse.getEntity();
        // 響應(yīng)狀態(tài)
        System.out.println("status:" + httpResponse.getStatusLine());
        System.out.println("headers:");
        HeaderIterator iterator = httpResponse.headerIterator();
        while (iterator.hasNext()) {
            System.out.println("	" + iterator.next());
        }
        // 判斷響應(yīng)實(shí)體是否為空
        if (entity != null) {
            String responseString = EntityUtils.toString(entity);
            System.out.println("response length:" + responseString.length());
            System.out.println("response content:"
                    + responseString.replace("
", ""));
        }
    }
 
    public static Map cookieMap = new HashMap(64);
    //從響應(yīng)信息中獲取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);
    }
}

代碼的流程是:

從知乎首頁獲取xsrf信息。

post請(qǐng)求當(dāng)中需要cookie信息,但是我們第一步中沒有得到cookie,請(qǐng)?jiān)跒g覽器中自行找到cookie添加進(jìn)去,上邊的cookie是我找到的。

提交post請(qǐng)求,得到登錄用cookie

隨便找一個(gè)需要登錄的子頁面,將得到的cookie寫入到請(qǐng)求頭中,提交請(qǐng)求,查看是否已經(jīng)登錄成功

四 結(jié)果驗(yàn)證

第一張圖顯示得到cookie并登錄成功

第二張圖顯示已經(jīng)進(jìn)入需要登錄的界面

總結(jié)

當(dāng)我們需要登錄一個(gè)界面獲取信息的時(shí)候,我們要知道登錄實(shí)際上做了什么,那就是讀寫cookie,post數(shù)據(jù)。

獲取cookie時(shí),需要從響應(yīng)頭中獲取,當(dāng)服務(wù)器發(fā)來新的cookie信息時(shí)需要及時(shí)寫入。

當(dāng)我們能登錄一個(gè)網(wǎng)站的時(shí)候,如何對(duì)其內(nèi)容進(jìn)行操作,這里推薦jsoup,良心庫,仿jquery操作模式。

更多文章:http://blog.gavinzh.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64406.html

相關(guān)文章

  • 爬蟲入門到精通-headers的詳細(xì)講解(模擬登錄知乎

    摘要:本文章屬于爬蟲入門到精通系統(tǒng)教程第七講直接開始案例吧。本次我們實(shí)現(xiàn)如何模擬登陸知乎。 本文章屬于爬蟲入門到精通系統(tǒng)教程第七講 直接開始案例吧。 本次我們實(shí)現(xiàn)如何模擬登陸知乎。 1.抓包 首先打開知乎登錄頁 知乎 - 與世界分享你的知識(shí)、經(jīng)驗(yàn)和見解 注意打開開發(fā)者工具后點(diǎn)擊preserve log,密碼記得故意輸入錯(cuò)誤,然后點(diǎn)擊登錄 showImg(https://segmentfaul...

    changfeng1050 評(píng)論0 收藏0
  • [PHP] 又是知乎,用 Beanbun 爬取知乎用戶

    摘要:最近看了很多關(guān)于爬蟲入門的文章,發(fā)現(xiàn)其中大部分都是以知乎為爬取對(duì)象,所以這次我也以知乎為目標(biāo)來進(jìn)行爬取的演示,用到的爬蟲框架為編寫的。項(xiàng)目地址這次寫的內(nèi)容為爬取知乎的用戶,下面就是詳細(xì)說一下寫爬蟲的過程了。 最近看了很多關(guān)于爬蟲入門的文章,發(fā)現(xiàn)其中大部分都是以知乎為爬取對(duì)象,所以這次我也以知乎為目標(biāo)來進(jìn)行爬取的演示,用到的爬蟲框架為 PHP 編寫的 Beanbun。 項(xiàng)目地址:http...

    tomato 評(píng)論0 收藏0
  • 簡(jiǎn)單三步,用 Python 發(fā)郵件

    摘要:使用腳本發(fā)送郵件并不復(fù)雜。以下為思路導(dǎo)圖模塊與發(fā)送郵件相關(guān)的模塊是關(guān)于簡(jiǎn)單郵件傳輸協(xié)議的操作模塊,在發(fā)送郵件的過程中起到服務(wù)器之間互相通信的作用。 0. 前言 發(fā)送電子郵件是個(gè)很常見的開發(fā)需求。比如你寫了個(gè)監(jiān)控天氣的腳本,發(fā)現(xiàn)第二天要下雨,或者網(wǎng)站上關(guān)注的某個(gè)商品降價(jià)了,就可以發(fā)個(gè)郵件到郵箱來提醒自己。 使用 Python 腳本發(fā)送郵件并不復(fù)雜。不過由于各家郵件的發(fā)送機(jī)制和安全策略不同...

    haobowd 評(píng)論0 收藏0
  • 一鍵下載:將知乎專欄導(dǎo)出成電子書

    摘要:在知乎上,你一定關(guān)注了一些不錯(cuò)的專欄比如的編程教室。有需要的請(qǐng)?jiān)诠娞?hào)里回復(fù)爬蟲實(shí)戰(zhàn)源碼下載獲取知乎專欄下載器源碼,請(qǐng)?jiān)诠娞?hào)的編程教室里回復(fù)關(guān)鍵字知乎除了代碼外,本專欄打包好的也一并奉上,歡迎閱讀與分享。 老是有同學(xué)問,學(xué)了 Python 基礎(chǔ)后不知道可以做點(diǎn)什么來提高。今天就再用個(gè)小例子,給大家講講,通過 Python 和 爬蟲 ,可以完成怎樣的小工具。 在知乎上,你一定關(guān)注了...

    ivyzhang 評(píng)論0 收藏0
  • scrapy模擬登陸知乎--抓取熱點(diǎn)話題

    摘要:在抓取數(shù)據(jù)之前,請(qǐng)?jiān)跒g覽器中登錄過知乎,這樣才使得是有效的。所謂的模擬登陸,只是在中盡量的模擬在瀏覽器中的交互過程,使服務(wù)端無感抓包過程。若是幫你解決了問題,或者給了你啟發(fā),不要吝嗇給加一星。 折騰了將近兩天,中間數(shù)次想要放棄,還好硬著頭皮搞下去了,在此分享出來,希望有同等需求的各位能少走一些彎路。 源碼放在了github上, 歡迎前往查看。 若是幫你解決了問題,或者給了你啟發(fā),不要吝...

    leanxi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

lucas

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<