2010-03-06 1 views
1

Я разрабатываю программу, которая может войти на AWeber.com и выполнять массовый импорт данных. Скрипт использует библиотеки PHP cURL вместе со своими настройками CookieJar, чтобы обмануть обычного пользователя браузером.«Сессия истёк» и «Разрешить cookies» предупреждения при отправке формы POSTing через cURL

Сценарий отлично работает, разрешая вход в систему и изменяя списки, но когда дело доходит до публикации данных формы (в функции 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, первая или вторая? –

ответ

1

Возможно, это связано с тем, что вы закрываете ручку curl с curl_close между вызовами во время сеанса. Его следует закрывать только после завершения сеанса.

+0

Оба метода были опробованы, оба дали тот же результат. –

0

Возможно, вам потребуется прочитать данные заголовка ответа, которые отправляются обратно из первого запроса. Затем передайте информацию сеанса (JSSESSION/PHPSESSID/etc) в качестве информации cookie.

Я думаю, что ваш пост-файл данных сбрасывает данные cookie (не уверен, как). Используйте Firebug для контроля заголовков, которые отправляются и принимаются при выполнении этих операций. Затем проверьте файлы cookie, чтобы убедиться, что они не переопределены.

0

Вы должны проверить файл cookie. Если все в порядке, оно должно иметь информацию. Если нет, возможно, вы должны использовать cwd(), чтобы указать абсолютный путь.

1

Я думаю, что «под ключ» правильный.

Это может быть потому, что вы закрываете локон справиться с curl_close в между вызовами во время сессии. Он должен быть закрыт только после завершения сеанса .

Нельзя открывать два разных сеанса завивки. Попробуйте сделать все за один сеанс, а затем закройте сеанс.

Попробуйте добавить curl_close() в деструктор класса. Храните сессию curl в переменной. И получить доступ к нему, используя $ 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

У меня были некоторые проблемы с использованием завиток, когда задав пост-параметров, как Array. Вместо

curl_setopt($cu, CURLOPT_POSTFIELDS, $array); 

Я использую:

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

Это работает для меня тогда.

Смежные вопросы