Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Multi cURL, xmlsitemap, постоянный рост RAM 
:(
    Опции темы
Psytodelist
Дата 7.5.2012, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 5.3.2010

Репутация: нет
Всего: нет



Wolf1994, привел Ваш вариант в ООП-шный вид, не работает.
Пойду спрашивать на зарубежные сайты. Благодарю за помощь.
PM MAIL   Вверх
Wolf1994
Дата 7.5.2012, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Цитата(Psytodelist @  7.5.2012,  18:36 Найти цитируемый пост)
Wolf1994, привел Ваш вариант в ООП-шный вид, не работает.

Попробуйте на всякий случай в том виде, как есть. Вроде, ничего менять не надо.

Добавлено через 4 минуты и 27 секунд
Ошибся. Нужно сбрасывать счётчик $new_links_i; до добавления новых ссылок:
Код

<?php
//echo $uniqid;
class sitemap
{
    private $sitemap_urls = array();
    private $new_links = array();
    private $new_links_i = 0;
    private $base;
    private $protocol;
    private $domain;
    private $check = array();
    private $proxy = "";
    
    public function set_ignore($ignore_list){
        $this->check = $ignore_list;
    }
    public function set_proxy($host_port){
        $this->proxy = $host_port;
    }
    private function validate($url){
        $valid = true;
        foreach($this->check as $val)
        {
            if(stripos($url, $val) !== false)
            {
                $valid = false;
                break;
            }
        }
        return $valid;
    }
    
    private function multi_curl($urls){
        $curl_handlers = array();
//        foreach ($urls as $url) 
        for ($i=0; $i<$new_links_i; $i++)
        {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $urls [$i]);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            if (isset($this->proxy) && !$this->proxy == '') 
            {
                curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
            }
            $curl_handlers[] = $curl;
        }
        $new_links_i=0;

        $multi_curl_handler = curl_multi_init();
    
        foreach($curl_handlers as $key => $curl)
        {
            curl_multi_add_handle($multi_curl_handler,$curl);
        }
        
        do 
        {
            $multi_curl = curl_multi_exec($multi_curl_handler, $active);
        } 
        while ($multi_curl == CURLM_CALL_MULTI_PERFORM  || $active);
        
        foreach($curl_handlers as $curl)
        {
            if(curl_errno($curl) == CURLE_OK)
            {
                $content = curl_multi_getcontent($curl);
                $this->parse_content($content);
            }
        }
        curl_multi_close($multi_curl_handler);
        return true;
    }
    public function get_links($domain){
        
        $this->base = str_replace("http://", "", $domain);
        $this->base = str_replace("https://", "", $this->base);
        $host = explode("/", $this->base);
        $this->base = $host[0];
        $this->domain = trim($domain);
        if(strpos($this->domain, "http") !== 0)
        {
            $this->protocol = "http://";
            $this->domain = $this->protocol.$this->domain;
        }
        else
        {
            $protocol = explode("//", $domain);
            $this->protocol = $protocol[0]."//";
        }
        
        if(!in_array($this->domain, $this->sitemap_urls))
        {
            $this->sitemap_urls[] = $this->domain;
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->domain);
        if (isset($this->proxy) && !$this->proxy == '') 
        {
            curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $page = curl_exec($curl);
        curl_close($curl);
        $this->parse_content($page);
        while ($new_links_i>0)
         multi_curl($new_links);
    }
    
    private function parse_content($page){
        preg_match_all("/<a[^>]*href\s*=\s*'([^']*)'|".
                    '<a[^>]*href\s*=\s*"([^"]*)"'."/is", $page, $match);
//        $new_links = array();
        for($i = 1; $i < sizeof($match); $i++)
        {
            foreach($match[$i] as $url)
            {
                if(strpos($url, "http") === false  && trim($url) !== "")
                {
                    if($url[0] == "/") $url = substr($url, 1);
                    else if($url[0] == ".")
                    {
                        while($url[0] != "/")
                        {
                            $url = substr($url, 1);
                        }
                        $url = substr($url, 1);
                    }
                    $url = $this->protocol.$this->base."/".$url;
                }
                if(!in_array($url, $this->sitemap_urls) && trim($url) !== "")
                {
                    if($this->validate($url))
                    {
                        if(strpos($url, "http://".$this->base) === 0 || strpos($url, "https://".$this->base) === 0)
                        {
                            $this->sitemap_urls[] = $url;
                            
                             mysql_query("UPDATE scans SET lastlink='".$url."', linkcounter=linkcounter+1");
                            $new_links[$new_links_i] = $url;
                            $new_links_i++;
                        }
                    }
                }
            }
        }
//        $this->multi_curl($new_links);
        return true;
    }
    public function get_array(){
        return $this->sitemap_urls;
    }
    public function generate_sitemap(){
        $sitemap = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
        foreach($this->sitemap_urls as $url) 
        {
            $url_tag = $sitemap->addChild("url");
            $url_tag->addChild("loc", htmlspecialchars($url));
        }
        return $sitemap->asXML();
    }
}
?>

PM MAIL WWW   Вверх
Psytodelist
  Дата 7.5.2012, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 5.3.2010

Репутация: нет
Всего: нет



Wolf1994, обращение к методам и свойствам происходит через this->
Опубликовал вопросец. Будем наблюдать что напишут.
http://stackoverflow.com/questions/1048531...ontent-variable
PM MAIL   Вверх
Wolf1994
Дата 7.5.2012, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Тогда так:

Код

        while ($new_links_i>0)
         $this->multi_curl($new_links);


 + сброс счётчика в подходящем месте.
PM MAIL WWW   Вверх
Psytodelist
Дата 7.5.2012, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 5.3.2010

Репутация: нет
Всего: нет



Цитата(Wolf1994 @ 7.5.2012,  19:23)
Тогда так:

Код

        while ($new_links_i>0)
         $this->multi_curl($new_links);


 + сброс счётчика в подходящем месте.

Лучше уж так  smile 
Код

        while ($this->$new_links_i>0)
         $this->multi_curl($new_links);


Добавлено через 3 минуты и 13 секунд
Инглишмэны не отзывчивые какие-то.
Пойду посплю, может, прозрение настанет какое
и Ваш вариант попробую. Благодарю за внимание  smile  smile 

Это сообщение отредактировал(а) Psytodelist - 7.5.2012, 19:27
PM MAIL   Вверх
Wolf1994
Дата 7.5.2012, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Так ещё лучше:

Код

        while ($this->new_links_i>0)
         $this->multi_curl($new_links);


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

Добавлено через 2 минуты и 19 секунд
Код

        while ($this->new_links_i>0)
         $this->multi_curl($this->new_links);

PM MAIL WWW   Вверх
Psytodelist
Дата 7.5.2012, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 5.3.2010

Репутация: нет
Всего: нет



А есть перевести все на простой cURL, то же самое придется делать?

Добавлено через 1 минуту
Тоже самое будет походу. 
PM MAIL   Вверх
Wolf1994
Дата 7.5.2012, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Иправил все опечатки. Попробуйте выполнить этот код:

Код

<?php
//echo $uniqid;
class sitemap
{
    private $sitemap_urls = array();
    private $new_links = array();
    private $new_links_i = 0;
    private $base;
    private $protocol;
    private $domain;
    private $check = array();
    private $proxy = "";
    
    public function set_ignore($ignore_list){
        $this->check = $ignore_list;
    }
    public function set_proxy($host_port){
        $this->proxy = $host_port;
    }
    private function validate($url){
        $valid = true;
        foreach($this->check as $val)
        {
            if(stripos($url, $val) !== false)
            {
                $valid = false;
                break;
            }
        }
        return $valid;
    }
    
    private function multi_curl(){
        $curl_handlers = array();
        for ($i=0; $i<$this->new_links_i; $i++)
        {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $this->new_links [$i]);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            if (isset($this->proxy) && !$this->proxy == '') 
            {
                curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
            }
            $curl_handlers[] = $curl;
        }
        $this->new_links_i=0;

        $multi_curl_handler = curl_multi_init();
    
        foreach($curl_handlers as $key => $curl)
        {
            curl_multi_add_handle($multi_curl_handler,$curl);
        }
        
        do 
        {
            $multi_curl = curl_multi_exec($multi_curl_handler, $active);
        } 
        while ($multi_curl == CURLM_CALL_MULTI_PERFORM  || $active);
        
        foreach($curl_handlers as $curl)
        {
            if(curl_errno($curl) == CURLE_OK)
            {
                $content = curl_multi_getcontent($curl);
                $this->parse_content($content);
            }
        }
        curl_multi_close($multi_curl_handler);
        return true;
    }
    public function get_links($domain){
        
        $this->base = str_replace("http://", "", $domain);
        $this->base = str_replace("https://", "", $this->base);
        $host = explode("/", $this->base);
        $this->base = $host[0];
        $this->domain = trim($domain);
        if(strpos($this->domain, "http") !== 0)
        {
            $this->protocol = "http://";
            $this->domain = $this->protocol.$this->domain;
        }
        else
        {
            $protocol = explode("//", $domain);
            $this->protocol = $protocol[0]."//";
        }
        
        if(!in_array($this->domain, $this->sitemap_urls))
        {
            $this->sitemap_urls[] = $this->domain;
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->domain);
        if (isset($this->proxy) && !$this->proxy == '') 
        {
            curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $page = curl_exec($curl);
        curl_close($curl);
        $this->parse_content($page);
        while ($this->new_links_i>0)
         $this->multi_curl();
    }
    
    private function parse_content($page){
        preg_match_all("/<a[^>]*href\s*=\s*'([^']*)'|".
                    '<a[^>]*href\s*=\s*"([^"]*)"'."/is", $page, $match);
        for($i = 1; $i < sizeof($match); $i++)
        {
            foreach($match[$i] as $url)
            {
                if(strpos($url, "http") === false  && trim($url) !== "")
                {
                    if($url[0] == "/") $url = substr($url, 1);
                    else if($url[0] == ".")
                    {
                        while($url[0] != "/")
                        {
                            $url = substr($url, 1);
                        }
                        $url = substr($url, 1);
                    }
                    $url = $this->protocol.$this->base."/".$url;
                }
                if(!in_array($url, $this->sitemap_urls) && trim($url) !== "")
                {
                    if($this->validate($url))
                    {
                        if(strpos($url, "http://".$this->base) === 0 || strpos($url, "https://".$this->base) === 0)
                        {
                            $this->sitemap_urls[] = $url;
                            
                             mysql_query("UPDATE scans SET lastlink='".$url."', linkcounter=linkcounter+1");
                            $this->new_links[$this->new_links_i] = $url;
                            $this->new_links_i++;
                        }
                    }
                }
            }
        }
        return true;
    }
    public function get_array(){
        return $this->sitemap_urls;
    }
    public function generate_sitemap(){
        $sitemap = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
        foreach($this->sitemap_urls as $url) 
        {
            $url_tag = $sitemap->addChild("url");
            $url_tag->addChild("loc", htmlspecialchars($url));
        }
        return $sitemap->asXML();
    }
}
?>

PM MAIL WWW   Вверх
Psytodelist
Дата 7.5.2012, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 5.3.2010

Репутация: нет
Всего: нет



А без перевода параллельного на последовательное нельзя никак?
Я ж вроде все толково с $GLOBALS написал... вместо переменной
глобальный массив с уникальным идентификатором...
Точно ведь должен знать, какой элемент массива ансетить.
Причем скрипт работал отлично при этом варианте,
но ситуация с ростом оперативной памяти была та же.  smile

Добавлено через 34 секунды
Ок, сейчас попробую просто скопировать и запустить.

Добавлено через 5 минут и 17 секунд
Цитата

memory_get_usage(): 475344
memory_get_usage(): 815640
memory_get_usage(): 1003056
memory_get_usage(): 955632


те же результаты, только чуть хуже,
потому что в этом варианте 
нет ансета $page походу
PM MAIL   Вверх
Wolf1994
Дата 7.5.2012, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Код

    private function multi_curl(){
    print $this->new_links_i;// Узнайте значение счётчика
   $this->new_links_i=$this->new_links_i/10;// И уменьшите


Если много ссылок, то остаётся разбить один cURL_multi на несколько запросов с небольшим количеством URL'ов.

Добавлено через 1 минуту и 6 секунд
Пример выше - только для теста.
PM MAIL WWW   Вверх
Wolf1994
Дата 7.5.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Так правильнее:

Код

    private function multi_curl(){
    print $this->new_links_i;// Узнайте значение счётчика
    if ($this->new_links_i>100)
     $this->new_links_i=100;// И уменьшите


- сработает при первых проходах на небольших количествах ссылок.
PM MAIL WWW   Вверх
Wolf1994
Дата 8.5.2012, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

Репутация: нет
Всего: 29



Если меньше запросов в cURL_multi уменьшили потреление RAM, то такой скрипт должен полностью решить проблему:

Код

<?php
//echo $uniqid;
class sitemap
{
    private $sitemap_urls = array();
    private $new_links = array();
    private $new_links_i = 0;
    private $base;
    private $protocol;
    private $domain;
    private $check = array();
    private $proxy = "";
    
    public function set_ignore($ignore_list){
        $this->check = $ignore_list;
    }
    public function set_proxy($host_port){
        $this->proxy = $host_port;
    }
    private function validate($url){
        $valid = true;
        foreach($this->check as $val)
        {
            if(stripos($url, $val) !== false)
            {
                $valid = false;
                break;
            }
        }
        return $valid;
    }
    
    private function multi_curl($urls){
        $curl_handlers = array();
//        for ($i=0; $i<$this->new_links_i; $i++)
        foreach ($urls as $value)
        {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $value);//$this->$urls [$i]
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            if (isset($this->proxy) && !$this->proxy == '') 
            {
                curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
            }
            $curl_handlers[] = $curl;
        }
//        $this->new_links_i=0;

        $multi_curl_handler = curl_multi_init();
    
        foreach($curl_handlers as $key => $curl)
        {
            curl_multi_add_handle($multi_curl_handler,$curl);
        }
        
        do 
        {
            $multi_curl = curl_multi_exec($multi_curl_handler, $active);
        } 
        while ($multi_curl == CURLM_CALL_MULTI_PERFORM  || $active);
        
        foreach($curl_handlers as $curl)
        {
            if(curl_errno($curl) == CURLE_OK)
            {
                $content = curl_multi_getcontent($curl);
                $this->parse_content($content);
            }
        }
        curl_multi_close($multi_curl_handler);
        return true;
    }
    public function get_links($domain){
        
        $this->base = str_replace("http://", "", $domain);
        $this->base = str_replace("https://", "", $this->base);
        $host = explode("/", $this->base);
        $this->base = $host[0];
        $this->domain = trim($domain);
        if(strpos($this->domain, "http") !== 0)
        {
            $this->protocol = "http://";
            $this->domain = $this->protocol.$this->domain;
        }
        else
        {
            $protocol = explode("//", $domain);
            $this->protocol = $protocol[0]."//";
        }
        
        if(!in_array($this->domain, $this->sitemap_urls))
        {
            $this->sitemap_urls[] = $this->domain;
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->domain);
        if (isset($this->proxy) && !$this->proxy == '') 
        {
            curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $page = curl_exec($curl);
        curl_close($curl);

        $this->parse_content($page);

        while ($this->new_links_i>0)
        {
         $new_links_tmp=array ();
         for ($i=0; $i<$this->new_links_i; $i++)
          $new_links_tmp [$i]=$this->new_links [$i];
         $size=sizeof ($new_links_tmp);
         if ($size>=200)
          $new_links_tmp2=array_chunk ($new_links_tmp, intval ($size/100));
         else
          $new_links_tmp2 [0]=$new_links_tmp;

         $this->new_links_i=0;

         foreach ($new_links_tmp2 as $value)
          $this->multi_curl($value);
         unset ($new_links_tmp);
        }
    }
    
    private function parse_content($page){
        preg_match_all("/<a[^>]*href\s*=\s*'([^']*)'|".
                    '<a[^>]*href\s*=\s*"([^"]*)"'."/is", $page, $match);
        for($i = 1; $i < sizeof($match); $i++)
        {
            foreach($match[$i] as $url)
            {
                if(strpos($url, "http") === false  && trim($url) !== "")
                {
                    if($url[0] == "/") $url = substr($url, 1);
                    else if($url[0] == ".")
                    {
                        while($url[0] != "/")
                        {
                            $url = substr($url, 1);
                        }
                        $url = substr($url, 1);
                    }
                    $url = $this->protocol.$this->base."/".$url;
                }
                if(!in_array($url, $this->sitemap_urls) && trim($url) !== "")
                {
                    if($this->validate($url))
                    {
                        if(strpos($url, "http://".$this->base) === 0 || strpos($url, "https://".$this->base) === 0)
                        {
                            $this->sitemap_urls[] = $url;
                            
                             mysql_query("UPDATE scans SET lastlink='".$url."', linkcounter=linkcounter+1");
                            $this->new_links[$this->new_links_i] = $url;
                            $this->new_links_i++;
                        }
                    }
                }
            }
        }
        return true;
    }
    public function get_array(){
        return $this->sitemap_urls;
    }
    public function generate_sitemap(){
        $sitemap = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
        foreach($this->sitemap_urls as $url) 
        {
            $url_tag = $sitemap->addChild("url");
            $url_tag->addChild("loc", htmlspecialchars($url));
        }
        return $sitemap->asXML();
    }
}
?>

PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.1357 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.