MultiCurl + proxy, user_agent - не работает как следует

Тема в разделе "PHP", создана пользователем sasha_ua, 25 фев 2011.

Модераторы: latteo
  1. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    PHP:
    <?php

    // страницы, содержимое которых надо получить
    $urls = array("link1""link2""link3""link4");
     
    // инициализируем "контейнер" для отдельных соединений (мультикурл)
    $cmh curl_multi_init();
     
    // массив заданий для мультикурла
    $tasks = array();
    // перебираем наши урлы
    foreach ($urls as $url) {
        
        
    $proxy =  get_rand_proxy(); // Запрос произвольного прокси
        
    $uagent get_rand_uagent(); // Запрос произвольного юзнр-агента

        // инициализируем отдельное соединение (поток)
        
    $ch curl_init($url);
        
    // задаем прокси-сервер
        
    curl_setopt($chCURLOPT_PROXY$proxy);
        
    // задаем юзер-агент
        
    curl_setopt($chCURLOPT_USERAGENT$uagent);
        
    // если будет редирект - перейти по нему
        
    curl_setopt($chCURLOPT_FOLLOWLOCATION1);
        
    // возвращать результат
        
    curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
    // не возвращать http-заголовок
        
    curl_setopt($chCURLOPT_HEADER0);
        
    // таймаут соединения
        
    curl_setopt($chCURLOPT_CONNECTTIMEOUT20);
        
    // таймаут ожидания
        
    curl_setopt($chCURLOPT_TIMEOUT20);
        
    // добавляем дескриптор потока в массив заданий
        
    $tasks[$url] = $ch;
        
        
    // добавляем дескриптор потока в мультикурл
        
    curl_multi_add_handle($cmh$ch);
    }
     
    // количество активных потоков
    $active null;

    // запускаем выполнение потоков
    do {
        
    $mrc curl_multi_exec($cmh$active);
    }
    while (
    $mrc == CURLM_CALL_MULTI_PERFORM);
     
    // выполняем, пока есть активные потоки
    while ($active && ($mrc == CURLM_OK)) {
        
    // если какой-либо поток готов к действиям
        
    if (curl_multi_select($cmh) != -1) {
            
    // ждем, пока что-нибудь изменится
            
    do {
                
    $mrc curl_multi_exec($cmh$active);
                
    // получаем информацию о потоке
                
    $info curl_multi_info_read($cmh);
                
    // если поток завершился
                
    if ($info['msg'] == CURLMSG_DONE) {
                    
    $ch $info['handle'];
                    
    // ищем урл страницы по дескриптору потока в массиве заданий
                    
    $url array_search($ch$tasks);
                    
    // забираем содержимое
                    
    $tasks[$url] = curl_multi_getcontent($ch);
                    
                    
    // удаляем поток из мультикурла
                    
    curl_multi_remove_handle($cmh$ch);
                    
    // закрываем отдельное соединение (поток)
                    
    curl_close($ch);
                }
            }
            while (
    $mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
    print_r($tasks);
    // закрываем мультикурл
    curl_multi_close($cmh);
     
    ?>
    Проблема:
    1. Если закомментировать:
    Страницы скачиваются, но не всегда до конца, возможно таймаут низкий.
    2. Если закомментировать:
    Вудет выдавать Bad Request

    Вопросы:
    1. Что неправильно в коде?
    2. Как добавить подстановку другого прокси, если предыдущий оказался нерабочий, или страница загружена не полностью?
     
  2. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    через curl_errno получаешь код ошибки, далее обрабатываешь ошибку и, если ошибка в прокси(CURLE_COULDNT_RESOLVE_PROXY), меняешь прокси и пробуешь зайти под ней. Все просто.
    Вот список кодов ошибок:
    http://curl.haxx.se/libcurl/c/libcurl-errors.html
     
  3. fly21

    fly21 Создатель

    Регистр.:
    11 авг 2009
    Сообщения:
    19
    Симпатии:
    2
    Указание юзверь агента не должно влиять на полноту скачиваемой страницы. Если Вы не указываете явно какой юзверь агент передавать, то будет передан агент, который указан в php.ini в переменной конфигурации user_agent=....
    Возможно по этой причине сервер увидев какой-то левый агент обрывает соединение.