Предупреждения «Сессия истекла» и «Пожалуйста, включите куки» при размещении веб-сайта через форму - PullRequest
1 голос
/ 06 марта 2010

Я занимаюсь разработкой программы, которая позволяет входить на AWeber.com и выполнять массовый импорт данных. Сценарий использует библиотеки PHP cURL вместе с их настройками CookieJar для обмана обычного пользователя с помощью браузера.

Сценарий работает отлично, позволяя войти в систему и изменять списки, но когда дело доходит до публикации данных формы (в функции submitData), сценарий неизменно завершается неудачей. Каждый раз, когда веб-сайт будет выводить веб-страницу, указав, что сеанс истек, и попросив «пользователя» войти снова. Страница также просит «пользователя» включить куки в своем браузере.

Последние пару дней я проверил диагностику проблемы, и это меня полностью озадачило. Параметр 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'
?>

Ответы [ 5 ]

1 голос
/ 06 марта 2010

Я думаю, что под ключ это правильно.

Это может быть потому, что вы закрываете скручиваемая ручка с 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);

    }
}
?>
1 голос
/ 06 марта 2010

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

0 голосов
/ 05 ноября 2010

У меня были некоторые проблемы с использованием curl при указании параметров POST в качестве массива. Вместо

curl_setopt( $cu, CURLOPT_POSTFIELDS, $array );

Я использую:

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

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

0 голосов
/ 06 марта 2010

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

0 голосов
/ 06 марта 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...