天天看點

用curl模拟登陸擷取頁面資訊以及相關知識點

今天使用curl做了模拟登陸,之前沒有接觸過curl,也并不知道有這個東西,下面簡要談談我在做這個模拟登陸過程中get 到的技能以及了解到的知識:    

1、CURL:curl是利用URL文法開發的開源傳輸工具,相當于一個模拟浏覽器,可以通過post/get擷取到想要的頁面資訊、實作檔案的上傳下載下傳、操作cookies檔案、通過代理伺服器(代理伺服器是浏覽器和web伺服器的一個中轉站,相當于緩沖池)向伺服器發送請求等,支援如FTP,FTPS,TELNET等多種檔案傳輸協定。起初隻能在指令行中使用,現在也支援PHP,并且有一個強大的函數庫,裡面有很多函數可以支援不同的功能。之前采集頁面資訊的時候用的是file_get_contents,采集完整個頁面,然後再用正則比對擷取到想要的内容,對于某些登陸或者驗證後才能得到的資訊是擷取不到的。

curl發送url請求的步驟為:curl初始化---》 設定具體的參數資訊---》執行curl,并取得傳回的結果---》關閉curl會話

下面就是使用curl模拟登陸擷取使用者資訊的過程:

<span style="font-size:14px;">function login_post($url, $cookie, $post){  
                    $curl = curl_init($url);//初始化
                    curl_setopt($curl, CURLOPT_URL, $url);//登入送出的位址 
                    curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); //設定Cookie資訊儲存在指定的檔案中
                    curl_setopt($curl, CURLOPT_POST, 1);//post方式送出              
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $post);//要送出的資訊 
                    //var_dump(http_build_query($post));exit;//列印要post的資訊
                    $data = curl_exec($curl);//執行指令
                    curl_close($curl);//關閉URL請求
    }
    function get_content($url, $cookie) {
                    $ch = curl_init($url);
                    curl_setopt($ch, CURLOPT_URL, $url);//需要擷取資訊的頁面
                    //curl_setopt($ch, CURLOPT_HEADER, 1);//不輸出頭部
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);//設定将擷取到的資訊輸出在浏覽器上
                    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //讀取cookie
                    $rs = curl_exec($ch); //執行cURL抓取頁面内容
                    curl_close($ch);
                    return $rs;
        }
    //設定post資料
        $post = array(
                        "uname" => "xxxxxxxx",
                        "passwd" => "xxxxxx",
                           ……
                        );//這裡要傳輸的資料很重要,決定了能否成功登陸頁面,生成cookie檔案
                            //其實隻要post的資料正确,一般都能生成cookie檔案,之後就很簡單了。
        </span> //登入位址
        $url = "URL";
        $cookie = dirname(__FILE__) . '/cookie.txt';</span><span style="font-size:14px;"> // 設定cookie儲存路徑</span><span style="font-size:14px;">     
        $url2 = "URL";</span><span style="font-size:14px;">  //登入後要擷取資訊的頁面</span><span style="font-size:14px;">
        login_post($url, $cookie, $post);</span><span style="font-size:14px;">// 模拟登入</span><span style="font-size:14px;">
        $content = get_content($url2, $cookie);</span><span style="font-size:14px;">//擷取登入頁的資訊</span><span style="font-size:14px;">
        echo $content.'<hr/>';//比對頁面資訊
        $preg = '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/i';
        $bool = preg_match($preg,$content,$time);
        echo '注冊時間:'.$time[0]</span>;

           

2、php抓取頁面資訊的方式還有以下幾種

(1)file_get_contents($url)      會抓取整個頁面,列印傳回的結果是整個頁面

(2)file($url)     會抓取整個頁面,列印傳回的結果是數組(将頁面拆分後的結果),implode之後再列印就是整個頁面

(3)fopen()    要配合fread()和fclose()一起使用,抓取整個頁面,處理過後也可以列印整個頁面

3、cookie的原理

cookie就是伺服器在響應用戶端請求的時候通過在http響應頭上加一段特殊訓示(建立一個cookie對象)進而使浏覽器自動生成的一個儲存使用者資訊和狀态的小檔案。cookie隻在用戶端發送請求或者浏覽器自己具有建立cookie功能的時候會建立。cookie有會話cookie(儲存在記憶體中,一旦浏覽器關閉則自動銷毀,多視窗不能共享)和持久cookie(儲存在硬碟中,到了過期時間才會銷毀,同一個浏覽器的多個視窗可以共享)。浏覽器在發送請求的時候會在用戶端尋找是否有相應作用範圍的cookie檔案,如果有就會将cookie放在http的請求頭中一起發送給伺服器,伺服器再響應相應的内容。cookie内容主要包括:名字、值、過期時間、路徑和域(這兩者即構成cookie的作用範圍)

4、session的原理

session是儲存在伺服器端的資訊,散清單的結構。當浏覽器向伺服器端發送請求的時候,如果請求頭中有sessionid(一般會存在于cookie中,和cookie一起通過請求頭發送),那麼伺服器會根據這個sessionid找到伺服器上這個id對應的内容,根據請求資訊決定是否把相關資訊傳回給用戶端,如果沒有,則會為這個使用者建立一個session(在伺服器端調用HttpServletRequest.getSession(true)這種語句的時候才會建立,并且可以由使用者決定是建立檔案還是資料表等的形式),并将sessionid傳回給浏覽器并儲存。浏覽器端傳遞sessionid的方法可以有多種:

(1)在cookie中儲存sessionid,發送請求的時候直接附加在請求頭中

用curl模拟登陸擷取頁面資訊以及相關知識點

(2)通過URL重寫來發送sessionid,即把sessionid加在url的後面

步驟:

1)在伺服器端php.ini配置檔案中設定:session.use_cookies = 0  && session.use_only_cookie = 0  session.use_trans_sid = 1 

2)如果你使用的是nginx,那麼在nginx的檔案根目錄下建立一個index.php,内容如下:

<?php
session_start();
echo session_id();
echo "<a href=''>aa</a>";
?>
           

然後

I. 使用php指令直接在dos下解析php檔案(如:php index.php),這個時候就會有問題出現:

 如果你的lnmp伺服器中php的版本是5.7以上的版本,那麼在執行上述php index.php的時候是會報錯的,我這裡是報 core dumped;

II. 在浏覽器通過ip通路這個檔案的時候也會報錯

用curl模拟登陸擷取頁面資訊以及相關知識點

  如果你在浏覽器設定中禁用了cookie,那麼你每重新整理一次頁面,浏覽器就會向伺服器發送一次請求,但是因為php.ini中我們設定了sessionid不通過cookie傳遞,那麼在這次請求的頭中就沒有sessionid的資訊傳遞給伺服器,伺服器接收了請求之後,沒有發現sessionid,那麼它會自動生成一個session檔案,然後将sessionid響應給用戶端,那麼這個時候用戶端禁用了cookie之後,就不能用cookie來儲存這一個sessionid,是以當你再次重新整理頁面的時候,sessionid就不能傳遞給伺服器端進行比對,伺服器端就又會生成一個新的session檔案,每重新整理一次生成一個。

是以,用戶端不能夠設定禁用cookie,隻需要設定php.ini就可以 了,并且php版本最好是5.6及以下,那麼就能順利在url中看到sessionid

用curl模拟登陸擷取頁面資訊以及相關知識點

那麼做到這一步了之後,繼續深究又會發現問題,比如:

session_url.php:

<span style="font-size:14px;"><?php
session_start();
$_SESSION['vars'] = 'HELLO WORLD';
//echo "<a href=''>aa</a>";//點選aa可以看到sessionid加到了url中
//echo "<a href='http://172.16.233.128/a.php'>aa</a>";//sessionid沒有加到url中,并且沒有列印出a.php中的結果
echo "<a href='a.php'>aa</a>";//點選aa可以看到sessionid加到了url中,并且可以列印出a.php中的session中的值,同時你檢視
                              //頁面源代碼的時候發現a标簽中的href也已經加上了sessionid
?></span>
           

a:php:

<span style="font-size:14px;"><?php
echo $_SESSION['vars'];
?></span>
           

上面的結果差異性問題可能是跟nginx的行為有關系,具體沒有做更深入的探究,但是在沒有加ip位址的時候,如果是同一個域内的檔案,一般來說都是可以在url上自動加上sessionid

(3)通過隐藏表單的形式來傳遞sessionid,伺服器會自動修改表單

可以在form表單中設定一個隐藏input将session_id()傳遞給後端,也可以在後端直接擷取到session_id(),可以直接使用,也可以儲存到檔案中,這樣在通路同一台伺服器上的不同域的時候可以使用同一個sessionid;将session資訊儲存到資料庫中,然後另外一台伺服器也可以拿着檔案中的sessionid來通路這台伺服器中的session資訊,實作session共享

5、session和cookie的差別

session儲存在伺服器端,預設通過cookie的方式儲存sessionid,是以如果用戶端禁用了cookie,在伺服器端又沒有設定trans-sid選項的話,那麼sessionid是沒有地方儲存的,那麼session也就用不了;sessionid一般儲存在會話cookie中,是以一般關閉浏覽器就找不到這個sessionid了;安全性較高,可以存儲使用者名密碼之類的重要資訊。

cookie儲存在浏覽器端,安全性沒有session那麼高,可以存儲一些不太重要的資訊。

6、伺服器比對驗證碼的機制

伺服器端在用戶端請求的時候,首先随機生成一串字元串儲存在session中,然後将字元串寫入圖檔,發送給浏覽器顯示,客戶輸入看到的字元串,傳回給伺服器端,與session中儲存的字元串進行比對。

7、hosts檔案和dns域名解析系統

hosts檔案中存儲的是ip和域名的一個對應關系。使用者在通路一個域名的時候,需要找到該域名對應的ip,那麼首先,用戶端會先給本地域名伺服器發送請求,本地域名伺服器會在自己的映射表中查找是否有這個域名對應的ip,如果有,則向用戶端傳回這個ip,如果沒有,那麼就會繼續發送請求給根域名伺服器,根域名伺服器在自己的映射表中查找所請求的那個域的主域名伺服器的ip,然後傳回給本地dns,本地dns再向主域名伺服器發送請求,主域名伺服器要是沒有找到映射關系的話,就會傳回下一級的域名伺服器ip,直到找到正确的ip,然後傳回給本地dns,然後本地dns會将此映射關系寫入緩存,同時傳回給用戶端。

用curl模拟登陸擷取頁面資訊以及相關知識點

8、http和https

使用者在使用浏覽器發送請求的時候使用的是http和https協定,這兩種都是超文本傳輸協定,差別是,https是加密傳輸協定,使用了ssl套接字層,對資料進行加密了之後再傳輸,且需要申請數字證書,由伺服器端将證書發送給用戶端,用戶端先驗證這個證書是否可信任,如果可信任,那麼就會生成一個随機值,然後用這個證書給随機值加密,然後将加密後的随機值發送給伺服器端,伺服器端用證書進行解密,之後伺服器端和用戶端的通信就靠這個随機值對資料進行加解密傳輸。http和https都是建立在TCP/IP協定的基礎之上,是可靠的連接配接。

用curl模拟登陸擷取頁面資訊以及相關知識點

9、http請求傳回的狀态碼

1xx  : 提示資訊                         

2xx :成功

3xx  :重定向

4xx :用戶端錯誤   

5xx :伺服器端錯誤

比較常見的是302(請求網頁臨時移動到新位置)、403(伺服器拒絕請求)、404(找不到檔案)、500(伺服器遇到錯誤)等

狀态碼詳解:http://tool.oschina.net/commons?type=5

php