請教各位大神,我利用curl登入一個網站的時候登入失敗,能否麻煩大家指點一下。
首先說一下應用背景:
http://my.tri.co.id/login/init,
這個網站是一個電話諮詢查詢網站,用來查詢當前電話卡的流量,是印尼網站。
我想利用php做一個登入代理,實現自動查詢以及匯總。
這個網站在登入的時候有一個驗證碼,也就是伺服器通過session來建立使用者跟識別碼的一一對應關係。
我用curl實現了跟瀏覽器的post完全相同的raw data,但是依然登入失敗。
瀏覽器 raw stream:
721 bytes sent to 180.214.234.59:80
POST /login/submit HTTP/1.1
Host: my.tri.co.id
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://my.tri.co.id
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://my.tri.co.id/login/submit
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: BIGipServerSC_frontend_pool=123211018.37151.0000; JSESSIONID=BAD8502FE89E3929E468FCEB255DFA77
Content-Length: 68
modelName=login&msisdn=089506850651&password=indonesia&checkNum=6998
curl 類比的 raw stream:
721 bytes sent to 180.214.234.59:80
POST /login/submit HTTP/1.1
Host: my.tri.co.id
Cookie: BIGipServerSC_frontend_pool=123211018.37407.0000; JSESSIONID=EE68C4C157664FB0E964FFB1A950968A
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://my.tri.co.id
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://my.tri.co.id/login/submit
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Content-Length: 68
modelName=login&msisdn=089506850651&password=indonesia&checkNum=4608
但是返回的資料卻不同,也就是說我的程式返回的頁面不是登陸後成功的頁面。
瀏覽器返回:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=5830130390F707D68D4E465557B9F054; Path=/
Location: http://my.tri.co.id/
Content-Language: en-US
Date: Tue, 26 Jan 2016 14:13:19 GMT
Content-Length: 0
curl返回:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Vary: Accept-Encoding
Date: Tue, 26 Jan 2016 16:09:49 GMT
Content-Length: 5569
我的程式是下面的實現 login.php:
==========================================================
* @link http://hightman.cn * @copyright Copyright (c) 2015 Twomice Studio. */ // set cookie file $cookie_file = dirname(__FILE__) . '\cookie.txt'; echo $cookie_file . "
"; $usr_form_name = 'usr'; $pwd_form_name = 'pwd'; $check_num_form_name = 'check_num'; $post_url = 'http://my.tri.co.id/login/submit'; $usr = $_POST[$usr_form_name]; $pwd = $_POST[$pwd_form_name]; $check_num = $_POST[$check_num_form_name]; //echo $usr . " " . $pwd . " " .$check_num; $tri_usr_form_name = 'msisdn'; $tri_pwd_form_name = 'password'; $tri_check_num_form_name = 'checkNum'; $tri_mode_form_name = 'modelName'; $fields = array( $tri_mode_form_name => urlencode('login'), $tri_usr_form_name => urlencode($usr), $tri_pwd_form_name => urlencode($pwd), $tri_check_num_form_name => urlencode($check_num) ); //url-ify the data for the POST $fields_string = ''; foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value . '&'; } print $fields_string . "
"; $fields_string = substr($fields_string, 0, strlen($fields_string)-1); rtrim($fields_string, "&"); print $fields_string . "
"; //open connection $ch = curl_init(); $header[] = "Connection: keep-alive"; $header[] = "Cache-Control: max-age=0"; $header[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; $header[] = "Origin: http://my.tri.co.id"; $header[] = "Upgrade-Insecure-Requests: 1"; $header[] = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"; $header[] = "Content-Type: application/x-www-form-urlencoded"; $header[] = "Referer: http://my.tri.co.id/login/submit"; $header[] = "Accept-Encoding: gzip, deflate"; $header[] = "Accept-Language: en-US,en;q=0.8"; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //set the url, number of POST vars, POST data curl_setopt($ch, CURLOPT_URL, $post_url); curl_setopt($ch, CURLOPT_REFERER, 'http://my.tri.co.id'); //curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch ,CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); //使用上面擷取的cookies curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自動跳轉 curl_setopt($ch, CURLOPT_ENCODING, ""); //execute post $result = curl_exec($ch); if (!$result) { $error = curl_error(); echo $error . "
"; } else { print "result length: " . strlen($result) . "
"; } $rinfo=curl_getinfo($ch); curl_close($ch); print $result;
========================================================
這裡的思路是,我首先用(index.php, 登入介面的呈現) curl 實現了 cookie和登入識別碼圖片的擷取,然後 提交到我自己的login.php進行處理。login.php 的源碼如上所示,完成登入。
但不知道是什麼原因導致失敗。
真心請教各位,謝謝!
回複討論(解決方案)
先訪問表單頁,擷取 cookie 變數 JSESSIONID 和 BIGipServerSC_frontend_pool
再訪問校正碼url(帶上cookie變數),擷取 cookie 變數
***** 這裡有人工介入,所以必須以檔案方式儲存 cookie,並防止共用衝突(最好是以使用者id為檔案名稱)
提交表單資料(含校正碼)到表單目標頁(帶上cookie變數)
curl_setopt($ch ,CURLOPT_POSTFIELDS, $fields_string);
$fields_string 可以是關聯陣列,並不需要你費心組裝。如果一定想用字串,那也可以使用 http_build_query 函數
先訪問表單頁,擷取 cookie 變數 JSESSIONID 和 BIGipServerSC_frontend_pool
再訪問校正碼url(帶上cookie變數),擷取 cookie 變數
***** 這裡有人工介入,所以必須以檔案方式儲存 cookie,並防止共用衝突(最好是以使用者id為檔案名稱)
提交表單資料(含校正碼)到表單目標頁(帶上cookie變數)
curl_setopt($ch ,CURLOPT_POSTFIELDS, $fields_string);
$fields_string 可以是關聯陣列,並不需要你費心組裝。如果一定想用字串,那也可以使用 http_build_query 函數
cookie 已經在前一個頁面的處理中拿到了。在login.php中就是使用。我也查看了cookie的資料,session id資料是一樣的。另外從raw stream 的資料來看,所有的資料也是一樣。
但是登入就是不對。不知道您對這個現象怎麼看?
先訪問表單頁,擷取 cookie 變數 JSESSIONID 和 BIGipServerSC_frontend_pool
再訪問校正碼url(帶上cookie變數),擷取 cookie 變數
***** 這裡有人工介入,所以必須以檔案方式儲存 cookie,並防止共用衝突(最好是以使用者id為檔案名稱)
提交表單資料(含校正碼)到表單目標頁(帶上cookie變數)
curl_setopt($ch ,CURLOPT_POSTFIELDS, $fields_string);
$fields_string 可以是關聯陣列,並不需要你費心組裝。如果一定想用字串,那也可以使用 http_build_query 函數
我的處理流程也就是您這個思路。
* @link http://hightman.cn * @copyright Copyright (c) 2015 Twomice Studio. */header('content-type:text/html; charset=utf-8');//防止產生的頁面亂碼$title = '科技有限公司';$temp_file = 'template.html';$dest_file = 'login.html';// set cookie file$cookie_file = dirname(__FILE__) . '\cookie.txt';echo $cookie_file, PHP_EOL;//$http->setCookiePath($cookie_file);// simple load response contents$link_header = 'http://my.tri.co.id';$response_len = 0;$loop_times = 0;$login_url = $link_header . '/login/init';//先擷取cookies並儲存$ch = curl_init($login_url); //初始化curl_setopt($ch, CURLOPT_HEADER, 0); //不返回header部分curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //返回字串,而非直接輸出curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); //儲存cookiescurl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);$response = curl_exec($ch);curl_close($ch);//echo number_format(strlen($response)) . ' bytes', PHP_EOL;//echo $response;$img_link_header = '/verifycode;jsessionid';$img_link_tail = '?sessionKey=loginCN&null';$header_pos = strpos($response, $img_link_header);$tail_pos = strpos($response, $img_link_tail, $header_pos) + strlen($img_link_tail);//echo 'header pos: ' . $header_pos, PHP_EOL;//echo 'tail pos: ' . $tail_pos, PHP_EOL;$img_link = $link_header . substr($response, $header_pos, $tail_pos - $header_pos);$jsession_id_header = 'jsessionid=';$session_key_header = '?sessionKey';$session_id_pos = strpos($img_link, $jsession_id_header);$session_key_pos = strpos($img_link, $session_key_header);$session_id = substr($img_link, $session_id_pos + strlen($jsession_id_header), $session_key_pos - $session_id_pos - strlen($jsession_id_header));echo $img_link, PHP_EOL;echo $session_id, PHP_EOL;$fp = fopen($temp_file, "r"); //唯讀開啟模板$str = fread($fp, filesize($temp_file));//讀模數板中內容fclose($fp);$str = str_replace("{penglig_site_title}", $title, $str);//替換內容$str = str_replace("{img_url}", $img_link, $str);//替換內容echo $str;
從代碼可以看出,我也是先開啟第一個頁面,設定cookie,並且拿到驗證碼圖片的連結並在自己的網頁上顯示,人工進行識別並輸入,然後點擊自己的提交資料 post 到 login.php ,也就是1樓的代碼裡面去。
那你就跟蹤一下,看看那個環節出了問題
那你就跟蹤一下,看看那個環節出了問題
能具體講講怎麼調試跟蹤嗎?沒搞過這塊,經驗為0
謝謝