2010-03-06 27 views
1

我一直在開發一個能夠登錄到AWeber.com並執行海量數據導入的程序。該腳本使用PHP cURL庫以及它們的CookieJar設置來通過瀏覽器來欺騙普通用戶。當通過cURL發佈網站表單時,「Session expired」和「請啓用cookie」警告

該腳本完美工作,允許登錄和更改列表,但是當涉及發佈表單數據時(在submitData函數中)腳本總是失敗。每次網站輸出一個網頁,指示會話已過期,並要求「用戶」重新登錄。該頁面還要求「用戶」在其瀏覽器中啓用Cookie。

我已經花了幾天的時間來診斷問題,並且讓我完全陷入困境。 CURLOPT_VERBOSE設置表示cURL正在將cookie傳遞到網站,cookiejar文件包含cookie和其他因素,例如Referer和Javascript的要求已經從原因因素中消除。

我將不勝感激爲什麼這可能會發生和解決問題的任何建議。下面顯示導致錯誤的類和代碼。代碼標記出現錯誤的位置。

<?php 
class AWeber { 
    private $cj; 

    public function __construct() { 
    $this->cj = tempnam('/tmp', 'mlcookies_'); 
    } 

    private function postQuery($url, $array) { 
    $cu = curl_init(); 
    curl_setopt($cu, CURLOPT_URL, $url); 
    curl_setopt($cu, CURLOPT_POST, true); 
    curl_setopt($cu, CURLOPT_POSTFIELDS, $array); 
    curl_setopt($cu, CURLOPT_COOKIEJAR, $this->cj); 
    curl_setopt($cu, CURLOPT_COOKIEFILE, $this->cj); 
    curl_setopt($cu, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($cu, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($cu, CURLOPT_HEADER, true); 
    curl_setopt($cu, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'); 

    $return = curl_exec($cu); 
    echo $return; 
    curl_close($cu); 
    return $return; 
    } 

    private function getQuery($url) { 
    $cu = curl_init(); 
    curl_setopt($cu, CURLOPT_COOKIEJAR, $this->cj); 
    curl_setopt($cu, CURLOPT_COOKIEFILE, $this->cj); 
    curl_setopt($cu, CURLOPT_URL, $url); 
    curl_setopt($cu, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($cu, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($cu, CURLOPT_HEADER, true); 
    curl_setopt($cu, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'); 

    $return = curl_exec($cu); 
    curl_close($cu); 
    echo $return; 
    return $return; 
    } 

    public function login($user, $pass) { 
    $this->getQuery("https://www.aweber.com/login.htm"); // Get page cookie checks 
    $query = array(
     '_method' => 'POST', 
     'data[Account][username]' => $user, 
     'data[Account][password]' => $pass, 
     'data[Account][remember_login]' => '1' 
    ); 
    $return = $this->postQuery("https://www.aweber.com/login.htm", $query); 
    $this->getQuery("https://www.aweber.com/users/"); 
    if (!$return) return false; 
    if (strpos($return, '<div class="aw-status-headline">Error</div>') === false) { 
     return true; 
    } else { 
     return false; 
    } 
    } 

    public function setList($list) { 
    $return = $this->getQuery("https://www.aweber.com/users/lists/change/" . $list); 
    if (!$return) return false; 
    if (strpos($return, '<option selected="selected" id="listSelectionActiveOption" value="' . $list . '">') === false) { 
     return false; 
    } else { 
     return true; 
    } 
    } 

    public function submitData($text, $note) { 
    $query = array( 
     'upload_file' => '1', 
     'data[ImportWizard][leads]' => $text, 
     'data[ImportWizard][delimiter]' => 'TAB', 
     'data[ImportWizard][customer_note]' => $note, 
     'data[ImportWizard][use_automation]' => '1', 
     'cmd' => 'Next', 
    ); 
    $return = $this->postQuery("https://www.aweber.com/users/lead_imports", $query); 
    echo $return; 
    if (!$return || strpos($return, '<h1>Step 2</h1>') === false) return false; 

    $query = array(
     'columnArray' => '', 
     'columnArray' => '', 
     'data[ImportWizard][column0]' => 'name', 
     'data[ImportWizard][column1]' => 'email', 
     'cmd' => 'Save', 
    ); 
    $return = $this->postQuery("https://www.aweber.com/users/lead_imports", $query); 
    if (!$return || strpos($return, '<div class="aw-status-headline">Import Queued</div>') === false) return false; 
    return true; 
    } 

} 

$aw = new AWeber(); // Create new AWeber interface class instance 
$aw->login($aUser, $aPass) or trigger_error('Login failed', E_USER_ERROR); // Login 
$aw->setList('list1') or trigger_error('List change 1 failed', E_USER_ERROR); // Change mailing list to 'list1' 

// *** CODE WILL FAIL HERE WITH "Data submit 1 failed" ERROR *** 
$aw->submitData("Test\tTesterrr\nTest2\tTesterrr2\nTest3\tTesterrr3\n", "Testing Testing Testing Testing Testing Testing Testing") or trigger_error('Data submit 1 failed', E_USER_ERROR); // Submit data 
$aw->setList('list2') or trigger_error('List change 2 failed', E_USER_ERROR); // Change mailing list to 'list2' 
?> 
+0

哪個調用postQuery在submitData函數內失敗,第一次還是第二次? – 2010-03-08 10:56:01

回答

1

這可能是因爲你與curl_close電話之間的會話期間關閉卷曲手柄英寸它應該僅在會話使用完成後關閉。

+0

兩種方法都嘗試過,都產生了相同的結果。 – 2010-03-06 04:50:38

0

您可能需要讀取從第一個查詢發回的響應標頭數據。然後傳遞會話信息(JSSESSION/PHPSESSID/etc)作爲cookie信息。

我認爲您的發佈數據腳本正在重置cookie數據(不知道如何)。使用Firebug監視執行這些操作時發送和接收的標題。然後檢查cookie文件以確保它們不被覆蓋。

0

您應該檢查cookies文件。如果一切正常,它應該有信息。如果沒有,也許你應該使用cwd()指定一個絕對路徑。

1

我認爲Turnkey是正確的。

這可能是因爲您關閉 捲曲與curl_close手柄 會議期間調用之間。 只應在 會話使用完成後關閉。

您不能打開兩個不同的捲曲會話。 嘗試在一個會話中做所有事情,然後關閉會話。

嘗試在類的析構函數中添加curl_close()。將捲曲會話存儲在變量中。並使用$ this-> curl_session訪問它。 下面是一個例子

<?php 
    class AWeber { 
    $curl_session; 
    $cj; 
    function __construct() { 
     $this->curl_session = curl_init(); 
    } 
    function __destruct() { 
     if($this->curl_session) { 
      curl_close($this->curl_session); 
     } 
    } 
    function doWhatever() { 
      curl_setopt($this->curl_session, CURLOPT_COOKIEJAR, $this->cj); 
      curl_setopt($this->curl_session, CURLOPT_COOKIEFILE, $this->cj); 
      curl_setopt($this->curl_session, CURLOPT_URL, $url); 
      curl_setopt($this->curl_session, CURLOPT_RETURNTRANSFER, true); 
      curl_setopt($this->curl_session, CURLOPT_FOLLOWLOCATION, true); 
      curl_setopt($this->curl_session, CURLOPT_HEADER, true); 
      curl_setopt($this->curl_session, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'); 

      $return = curl_exec($this->curl_session); 

    } 
} 
?> 
0

我specifing的POST參數爲數組時使用curl一些問題。取而代之的

curl_setopt($cu, CURLOPT_POSTFIELDS, $array); 

我用:

curl_setopt($cu, CURLOPT_POSTFIELDS, http_build_query($array)); 

這爲我工作呢。