Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Сеть > Curl через раз возвращает ошибку 7


Автор: studentigor 27.7.2013, 13:34
Всем привет.

В общем есть сайт с объявлениями, он написан на asp.
Мне нужно спарсить объявления, предварительно авторизировавшись. Сразу скажу, на локалке все работает отлично.

Сама авторизация происходит в 3 этапа. followlocation не использую по этому для редиректе делаю ещё 1 дополнительный гет запрос.
Первый запрос, гет, я со страници с формой авторизации беру токен.
1й - Отправка формы авторизации(1 пост + 1гет для редиректа).
2й - соглашение какое-то(1 пост + 1гет для редиректа).
3й - смена языка(1 пост, гет запрос делаю уже когда начинаю парсить обьявы).

А вот у клиента на его сервере - както кривовато. В чем это видно.
Все может упасть либо на сомом первом гет запросе, а может дойти и до последнего пост запроса(смена языка).
Вот метод для авторизации
Код

$params = CMap::mergeArray(
            $this->getFormToken($this->authMainFormSettings, $this->authUrl), 
            array(
                '_ctl0:MAIN:MEMBER_CD'    => $login,
                '_ctl0:MAIN:WEB_MEMBER_PASSWORD' => $pass,
                '_ctl0:MAIN:MEMBER_KIND' => 'B',
                '_ctl0:MAIN:Button1' => '%25E3%2583%25AD%25E3%2582%25B0%25E3%2582%25A4%25E3%2583%25B3',
            )
        );
        $response = Curl::post($this->authUrl, $params);
        // Получаем переменные сессии и user_token
        $session = $this->getCookieValue($response, 'ASP.NET_SessionId');
        $this->authCookie = 'ASP.NET_SessionId='   . $session . '; ';
        $params = CMap::mergeArray(
            $this->getFormToken($this->authSecondSteapSettings, $this->authSecond), 
            array(
                '__EVENTTARGET' => '_ctl0%24MAIN%24LBtnAgree'
        ));
        $response = $this->getPostQuery($this->secondFormUrl, $params);
        $lenguageParams = CMap::mergeArray(
            $this->getFormToken($this->authMainFormSettings, $this->mainLoggedPage),
            array(
                '_ctl0%3AMAIN%3Abtn_NationChange.x' => '214',
                '_ctl0%3AMAIN%3Abtn_NationChange.y' => '25',
                '_ctl0%3AMAIN%3Ahid_info_count' => '13',
        ));
        $this->getPostQuery($this->mainLoggedPageEnglish, $lenguageParams);

Метод getFormToken, делает обычный гет запрос(он же редирект), и из полученного контента возращает просто значения необходимых полей(текена).

Код

protected function getPostQuery($url, $params)
    {
        $options = $this->authCookie 
            ? array(
                CURLOPT_COOKIE => $this->authCookie,
                CURLOPT_TIMEOUT => 100)
            : array();
            
        $responce = Curl::post($url, $params, $options);
        return $responce;
    }

public static function post($url, $post = array(), $options = array())
    {
        $options = $options + array(
                CURLOPT_POST           => true,
                CURLOPT_HEADER         => true,
                CURLOPT_COOKIESESSION  => true,
                CURLOPT_FRESH_CONNECT  => true,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_FORBID_REUSE   => true,
                CURLOPT_TIMEOUT        => 100,
                CURLOPT_URL            => $url,
                CURLOPT_POSTFIELDS     => http_build_query($post),
        );

        return self::execute($options);
    }

public static function get($url, $options = array())
    {
        $options = $options + array(
            CURLOPT_HEADER         => true,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL            => $url,
            CURLOPT_TIMEOUT        => 100,
            
        );

        return self::execute($options);
    }

public static function execute($options = array())
    {
        $curlSession = curl_init();
        curl_setopt_array($curlSession, $options);

        $curlResponse = curl_exec($curlSession);
        if($curlResponse === false) {
            throw new Exception(Yii::t('app', 'Ошибка cURL {code}: {message}', array(
                '{code}' => curl_errno($curlSession),
                '{message}' => curl_error($curlSession)
            )));
        }

        curl_close($curlSession);
        return $curlResponse;
    }



И вот я уже не знаю на что грешить, вроде как и курл работает, и хостинг не режет(доходит же до последнего пост запроса).
Но в итоге: Ошибка cURL 7: couldn't connect to host.


У меня такое бывало на локалке - но то у меня интернет отваливался.
Запустил на сервере и на локалке одновременно, в итоге на локалке парсит, а на сервере - ошибка.

Подскажите плиз, в чем может быть ошибка. Спасибо.

Автор: studentigor 10.8.2013, 10:34
В общем, проблемма на клиенском хостинге так и не решилась адекватными методами.
Единственное решение, над которым не пришлось долго думать, это зациклить execute.
Сделал так: Установыил число итераций, и когда делаю проверку результата, то в случае если его нет, вызываю себя же рекурсивно.
Ну и само сабой, добавил счетчик итераций. Если даже через несколько попыток соединится не удалось - возвращаю пустой html(заглушку).

Так получилось обойти эту проблемму, хотя и через костыль

Автор: lumentek 25.8.2018, 01:08
Было подобное с одним сервисом. Он банил подсети крупных хостинг провадеров. Прокси в курсе спасло.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)