Как вытянуть изображение из строки в которую CURL поместил веб-страницу?

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

Статус темы:
Закрыта.
Модераторы: latteo
  1. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    Доброго времени суток.
    Как извлекается страница с сайта:
    PHP:
    <?php
    function get_web_page($url// Берем страницу с помощью CURL через прокси.
    {
        
    $exit=0;
        do
        {
            
    $ch curl_init($url);
            
    curl_setopt($chCURLOPT_RETURNTRANSFER1);       // возвращает веб-страницу
            
    curl_setopt($chCURLOPT_HEADER0);               // не возвращает заголовки
            
    curl_setopt($chCURLOPT_FOLLOWLOCATION1);       // переходит по редиректам
            
    curl_setopt($chCURLOPT_ENCODING"");            // обрабатывает все кодировки
            
    curl_setopt($chCURLOPT_CONNECTTIMEOUT1);     // таймаут соединения
            
    curl_setopt($chCURLOPT_TIMEOUT60);            // таймаут ответа
            
    curl_setopt($chCURLOPT_MAXREDIRS10);           // останавливаться после 10-ого редиректа
            
    $content curl_exec$ch );
            
    $err     curl_errno$ch );
            
    $errmsg  curl_error$ch );
            
    $header  curl_getinfo$ch );    
            
    $header['errno']   = $err;
            
    $header['errmsg']  = $errmsg;
            
    $header['content'] = $content;
            if (
    strpos($header['content'], "site.com") AND strpos($header['content'], "text1") AND strpos($header['content'], "/html"))
            {
                
    $exit=1;
                return 
    $header['content'];
            }        
        }
        while(
    $exit==0);
        
    curl_close$ch );
    }
    $page_str get_web_page($url);
    ?>
    Мне интересно как извлечь изображения из $page_str?
     
  2. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145
    регулярным выражением вытаскиваете содержимое атрибута src тегов a
    типа такого
    PHP:
    '/<a[^>]*src=['"]([^'"]*)['"]/'
    а затем загружаете полученный URL(не забыв дописать к нему название домена, если надо) с помощью CURL-а же
    и да, эта функция должна быть изменена если вы хотите с ее помощью загрузить рисунок.
    перечень условий выхода в ней не подходит для рисунков
     
    sasha_ua нравится это.
  3. failometr

    failometr Постоялец

    Регистр.:
    30 апр 2009
    Сообщения:
    128
    Симпатии:
    45
    смотря конечно из какого тэга картинка, для img:
    PHP:
    if(preg_match('#<img[^>]*src=[\'"]?([^\'"]*)[\'"\s]#si'$page_str$match))
    copy($match[1], '/tmp/img.jpg'); // или 'c:\img.jpg'
    ну и смотря еще какой путь к картинке, абсолютный или нет. Если абсолютный, тогда замениш последнюю строку на
    PHP:
    copy('http://tvoj.domen'.$match[1], '/tmp/img.jpg');
    В общем конкретики добавить бы.
     
  4. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    Я наверное плохо сформулировал.

    Путь к картинке известен. Т.е. хочется вытянуть картинку из первого запроса и не генерировать второй, тем самым не создавая доп. нагрузку на сайт.

    Допустим скачанная страница содержит 10 картинок, тогда запросов будет 11 вместо одного..
     
  5. Mxnrl

    Mxnrl Постоялец

    Заблокирован
    Регистр.:
    29 апр 2010
    Сообщения:
    50
    Симпатии:
    1
    Весь контент у тебя в $page_str - и изображения ты будешь искать в ней. запрос один (в самом начале) так что нагрузки нет;)
     
  6. failometr

    failometr Постоялец

    Регистр.:
    30 апр 2009
    Сообщения:
    128
    Симпатии:
    45
    Но и каждая загрузка картинки это +1 неизбежный запрос.
     
  7. Belial

    Belial

    Регистр.:
    1 фев 2010
    Сообщения:
    236
    Симпатии:
    113
    Скачанная страница содержит только хтмл-код, в котором есть 10 ссылок на картинки. Чтобы получить картинку, нужно выдернуть ссылку на неё и сделать второй запрос. Чтобы получить 10 картинок - надо сделать 11 запросов.
     
    sasha_ua нравится это.
  8. sasha_ua

    sasha_ua Постоялец

    Регистр.:
    23 июн 2010
    Сообщения:
    66
    Симпатии:
    0
    Да, схитрить не получилось :)
    Всем спасибо за ответы!

    Не понимаю ка люди парсят такие ресурсы как Yandex Market?
    Напрямую без Прокси и Юзер агента, относительно недолго, но через прокси время увеличивается в 10 если не больше раз.
    Не знаю с чем сравнить, может кто подскажет.
    У меня 4500 позиций парсились 6 часов без Курла, (т.е. страница на которой 10 позиций + 10 страниц развернутой инф. + 2 картинки)
    1100 позиций через Курл - 10 часов!!! так это при том что картинки копировались без курла..
    Мне кажется что это нездоровые показатели, что скажете?
    Вот функция с настройками Курла:
    PHP:
    function get_web_page($url,$use_proxy// Берем страницу с помощью CURL через прокси.
    {
        
    $exit=0;
        do
        {
            if(
    $use_proxy==1) { $proxy get_rand_proxy(); }
            
    $uagent get_rand_uagent();
            
    $ch curl_init($url);
            
    curl_setopt($chCURLOPT_RETURNTRANSFER1);       // возвращает веб-страницу
            
    curl_setopt($chCURLOPT_HEADER0);               // не возвращает заголовки
            
    curl_setopt($chCURLOPT_FOLLOWLOCATION1);       // переходит по редиректам
            
    curl_setopt($chCURLOPT_ENCODING"");            // обрабатывает все кодировки
            
    curl_setopt($chCURLOPT_USERAGENT$uagent);      // useragent
            
    curl_setopt($chCURLOPT_CONNECTTIMEOUT1);     // таймаут соединения
            
    curl_setopt($chCURLOPT_TIMEOUT60);            // таймаут ответа
            
    curl_setopt($chCURLOPT_MAXREDIRS10);           // останавливаться после 10-ого редиректа
            
    if($use_proxy==1) { curl_setopt($chCURLOPT_PROXY$proxy); }
            
    $content curl_exec$ch );
            
    $err     curl_errno$ch );
            
    $errmsg  curl_error$ch );
            
    $header  curl_getinfo$ch );    
            
    $header['errno']   = $err;
            
    $header['errmsg']  = $errmsg;
            
    $header['content'] = $content;
            if (
    strpos($header['content'], "site.com") AND strpos($header['content'], "text1") AND strpos($header['content'], "/html"))
            {
                
    $exit=1;
                return 
    $header['content'];
            }        
        }
        while(
    $exit==0);
        
    curl_close$ch );
    }
    Пробовал поэксперементировать с:
    CURLOPT_CONNECTTIMEOUT
    CURLOPT_TIMEOUT
    разницы не заметил..
     
  9. chang

    chang

    Регистр.:
    20 ноя 2009
    Сообщения:
    364
    Симпатии:
    117
    sasha_ua
    1) скорее всего ты используешь публичные прокси - скорость их работы всегда желала лучше.

    к тому же если веб-сайт с которого пасишь каким-то образом палит что используется прокси и не желает чтоб его использовали он может выдавать страницу ошибки, на которой условие поиска
    PHP:
    if (strpos($header['content'], "site.com") AND strpos($header['content'], "text1") AND strpos($header['content'], "/html")) 
            {
    не выполнится и цикл соответственно пойдет на повторный круг ...



    2) по максимуму оптимизируй код. ПХП и так не самый быстрый.
    к примеру есть лишние проверки
    PHP:
    if($use_proxy==1) { $proxy get_rand_proxy(); }
    ....
    if(
    $use_proxy==1) { curl_setopt($chCURLOPT_PROXY$proxy); }
    можно вить проще написать

    PHP:
    function get_web_page($url,$use_proxy false){
    ....

    if(
    $use_proxy) {
       
    curl_setopt($chCURLOPT_PROXYget_rand_proxy(););
     }
    ну и действия
    PHP:
     $content curl_exec$ch ); 
            
    $err     curl_errno$ch );
    ...
        
    $header['errno']   = $err
            
    $header['errmsg']  = $errmsg;
    тоже лишние, т.к. результат их работы не используется

    ну и здесь условие неверное
    PHP:
        $exit=0
        do  {

    .....

           
    $header['content'] = $content
            if (
    strpos( ........) 
            { 
                
    $exit=1
                return 
    $header['content']; 
            }         
        }
        while(
    $exit==0); 
        
    curl_close$ch );
    при срабатывании return проверка while($exit==0); ненужная .. и соответственно переменная $exit лишняя
    ну и тогда curl_close( $ch ); не сработате

    наверн лучше будет так
    PHP:
    while(true){

           
    $header['content'] = $content

            if (
    strpos( ........) 
            { 
                 
    curl_close$ch );
                return 
    $header['content']; 
            }

    }
    но здесь как и в первом случае не учтена вероятность того что верное условие выхода может не наступить никогда ... к примеру сайт донор навернулся, или же изменил структуру страницы ... но так как цикл фактически до бесконечности, то предложу что это будет запускаться на выделенном сервере


    короче придирки к коду это фигня которая тормозить то й не будет ... а вот медленные прокси - это главный тормоз. А нормальные прокси денег стоят. Можете воспользоваться поиском по данному ресурсу - здесь часто различные прокси продают.

    а картинки дергать без курла - эт конечно зря... предположу что в выбранном вами способе копирования палится IP - тогда возможно и нет смысла использовать прокси
     
    sasha_ua нравится это.
  10. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145
    тормозные прокси.
    и я как погляжу вы не сделали никакой многопоточности, и это также тормозит.
    с многопоточностью дело гораздо быстрее пойдет
     
Статус темы:
Закрыта.