Парсинг статей в HostCMS 6.0+ на автомате

Тема в разделе "Импорт CSV", создана пользователем sersh, 5 ноя 2012.

  1. sersh

    sersh New Member Пользователи

    Регистрация:
    29 окт 2012
    Сообщения:
    5
    Хочу поделиться своим кодом парсинга статей в HostCMS версии 6.0 и выше. Можно наполнить систему тысячами элементов за пару часов, практически на автомате. При условии, что вы освоили программу парсинга. Написанно для тех, кто плохо разбирается в php.
    За основу взят код встроенного RSS импортера.
    Переделанный код:
    1. Заполняет все поля SEO
    2. Создает и присваивает метки (из заголовка)
    3. Присваивает фото к каждому элементу (если есть)
    4. Присваивает дату и время элементам
    5. Создает короткое описание из текста
    6. Присваивает названия элементам транслитерацией заголовка.
    7. Присваивает класс к импортируемым фото.
    8. Указывает источник.
    9. Позволяет проводить любую обработку файла перед импортом (например прописать адрес ко всем фото).
    10. Создает список импортированных элементов (с пометкой тех, у которых нет фото)
    Вроде все.

    Файл импорта должен иметь следующий предварительный формат шаблона вывода:
    PHP:
    <item>
    <
    title><CD_GRAN_1!></title>
    <
    link><CD_DOCURL!></link>
    <
    description><![CDATA[<CD_GRAN_2!>]]></description>
    <
    enclosure url="<NIMG><CD_GRAN_3!></NIMG>" type="image/jpeg"/>
    <
    pubDate><CD_GRAN_4!></pubDate>
    </
    item>
    -------------------------------------------------------------------
    Где:
    <
    CD_GRAN_1!> - заголовок
    <CD_DOCURL!> - адрес
    <CD_GRAN_2!> - текст
    <CD_GRAN_3!> - фото(если нет оставляем пустым)
    <
    CD_GRAN_4!> - дата(если нет оставляем пустым)
    Далее:
    1. Загружаем фото на сервер через ftp в нужную директорию(прописываем ее в коде(ниже)): "/dir1/.../dir-n/".
    2. Идем: Админ панель - Структура сайта - Раздел - Добавить - Типовая динамическая страница; Название - любое; Раздел - RSS; Страница - (Ваша страница с кодом(ниже), сделайте копию); Адрес - любой(я ставлю букву "i"); Код ИС - выбираете вашу ИС; Группа - ставим 0 (корень) или номер вашей группы; Источник: "http://your-site.com/import.xml" - Применить.
    3. Кидем в корень сайта файл импорта "article_all_1.php", и меняем его при каждом импорте, не забывайте прописывать правильные адреса к фото в коде и номер группы импорта в разделе структуры сайта.
    4. Отдельно стоит упомянуть про дату, код преобразования нужно изменять под конкретный сайт или оставляйте системную. Дату кстати можно убрать в xsl шаблоне, если она вам не нужна.
     
    Последнее редактирование: 5 ноя 2012
  2. sersh

    sersh New Member Пользователи

    Регистрация:
    29 окт 2012
    Сообщения:
    5
    Код стандартного импортера нужно заменить на следующий:
    PHP:
    <?php
    echo "<h1>Импорт информационных элементов</h1>";

    // Создание XML из файла предварительного формата
    $txt file_get_contents('article_all_1.php'); // Читаем файл предварительного формата из корня сайта
    $txt str_replace('<enclosure url="" type="image/jpeg"/>'''$txt); // Если нет фото элемента убираем строки с ссылкой на него
    $txt str_replace('&'' and '$txt); // Заменяем нечитаемый символ &
    $txt str_replace('images/''/dir1/.../dir-n/'$txt); // Прописываем адрес к фото (Относительно корня)
    $txt str_replace('url="/dir/''url="http://your-site.com/dir/'$txt); // Адрес к фото элемента (Обязательно полностью)

    /* Здесь любые обработки исходного файла */

    // $txt = trim(preg_replace('/[\r\n]+/m',"\n",$txt)); // Удаление пустых строк (Если нужно)
    $txt '<?xml version="1.0" encoding="windows-1251"?>'."\n".'<rss version="2.0">'."\n".'<channel>'."\n".$txt."\n".'</channel>'."\n".'</rss>'// Создание XML заголовка
    file_put_contents('import.xml'$txt); // Запись файла в формате XML


    $oInformationsystem Core_Entity::factory('Informationsystem',
        
    Core_Array::get(Core_Page::instance()->libParams'informationsystemId')
    );

    // Группа, в которую помещается новый элемент
    $oInformationsystem_Group Core_Entity::factory('Informationsystem_Group')->find(
        
    Core_Array::get(Core_Page::instance()->libParams'informationGroupId')
    );

    $aSourcesList explode("\n",
        
    Core_Array::get(Core_Page::instance()->libParams'sourcesList')
    );

    $iImported 0;

    $oCore_Rss_Read = new Core_Rss_Read();

    foreach (
    $aSourcesList as $url)
    {
        
    $aRssData $oCore_Rss_Read
            
    ->clear()
            ->
    loadUrl($url)
            ->
    parse();

        foreach (
    $aRssData['items'] as $itemKey => $aItem)
        {
            
    $oSameItem $oInformationsystem->Informationsystem_Items->getByName($aItem['title']);

            
    /* Если не найдено элементов с таким же именем */
            
    if (is_null($oSameItem))
            {
                
    $oInformationsystem_Item Core_Entity::factory('Informationsystem_Item');

                
    /* Заголовок */

                
    $zagolovok $aItem['title']; // Создаем переменную с содержание заголовка

                
    $oInformationsystem_Item->name $zagolovok// Запись в базу

                /* Дата */

                // Изменение формата даты в формат RSS (Только пример)
                // Исходный формат: <pubDate>10 января 2010 в 19:01</pubDate>
                // формат  RSS : <pubDate>Sun, 28 Oct 2012 14:28:56 +0400</pubDate>
                
                /*
                $date = $aItem['pubdate'];  // Исходный формат даты
                $date = str_replace(' в', '', $date);
                $date = str_replace('<pubDate>', '<pubDate>Mon, ', $date);
                $date = str_replace('</pubDate>', ':00 +0300</pubDate>', $date);

                $date = str_replace('января', 'Jan', $date);
                $date = str_replace('февраля', 'Feb', $date);
                $date = str_replace('марта', 'Mar', $date);
                $date = str_replace('апреля', 'Apr', $date);
                $date = str_replace('мая', 'May', $date);
                $date = str_replace('июня', 'Jun', $date);
                $date = str_replace('июля', 'Jul', $date);
                $date = str_replace('августа', 'Aug', $date);
                $date = str_replace('сентября', 'Sep', $date);
                $date = str_replace('октября', 'Oct', $date);
                $date = str_replace('ноября', 'Nov', $date);
                $date = str_replace('декабря', 'Dec', $date);

                $oInformationsystem_Item->datetime = Core_Date::timestamp2sql(strtotime($date)); // Дата элемента
                */

                
    $date date("Y-m-d H:i:s"); // Текущее время и дата (Сервера)
                
                
    $oInformationsystem_Item->datetime $date// Дата элемента

                /* SEO */

                // Создаем SEO-ключевые слова
                
    $kluchi preg_replace('/[^a-zA-ZА-Яа-я0-9\s]/u','',$zagolovok); // Удаляем все символы кроме букв и цифр
                
    $kluchi mb_strtolower($kluchi'UTF8'); // Переводим все буквы в строчные
                // Удаляем слова с количеством символов менне трех
                
    $kluchi explode(' '$kluchi);
                for(
    $i 0$c count($kluchi); $i $c$i++)
                {
                    if(
    mb_strlen($kluchi[$i], 'UTF8') < 3)
                    unset(
    $kluchi[$i]);
                }
                
    $kluchi implode(" "$kluchi);
                
    $kluchi str_replace(' ',', ',$kluchi); // Разделяем теги запятыми

                
    $oInformationsystem_Item->seo_keywords $kluchi// SEO-ключевые слова
                
    $oInformationsystem_Item->seo_title $zagolovok// SEO-заголовок
                
    $oInformationsystem_Item->seo_description $zagolovok// SEO-описание

                /* Описание */

                
    $opisaniye $aItem['description'];

                
    $opisaniye strip_tags($opisaniye); // Удаляем все теги (фото) из описания
                
    $opisaniye mb_substr($opisaniye0211 1) . "..."// Ограничиваем количество символов в описании (211)

                
    $oInformationsystem_Item->description $opisaniye// Описание элемента

                /* Текст */

                
    $tekst $aItem['description'];

                
    // Присвоение класса к фото
                
    $tekst str_replace('.jpg"''.jpg" class="news_photo" '$tekst);
                
    $tekst str_replace('.jpeg"''.jpeg" class="news_photo" '$tekst);
                
    $tekst str_replace('.gif"''.gif" class="news_photo" '$tekst);
                
    $tekst str_replace('.png"''.png" class="news_photo" '$tekst);
                
    $tekst str_replace('.JPG"''.jpg" class="news_photo" '$tekst);
                
    $host parse_url($aItem['link'], PHP_URL_HOST); // Выделяем имя домена из url-адреса

                
    $oInformationsystem_Item->text $tekst "<p style='color: #999;'>Источник: {$host}</p>";  // Текст элемента

                /* Адрес элемента (Транслитерация) */

                
    if (!function_exists('rus2translit'))
                {
                    function 
    rus2translit($string)
                    {
                    
    $converter = array
                        (
                        
    'а' => 'a',   'б' => 'b',   'в' => 'v',
                        
    'г' => 'g',   'д' => 'd',   'е' => 'e',
                        
    'ё' => 'e',   'ж' => 'zh',  'з' => 'z',
                        
    'и' => 'i',   'й' => 'y',   'к' => 'k',
                        
    'л' => 'l',   'м' => 'm',   'н' => 'n',
                        
    'о' => 'o',   'п' => 'p',   'р' => 'r',
                        
    'с' => 's',   'т' => 't',   'у' => 'u',
                        
    'ф' => 'f',   'х' => 'h',   'ц' => 'c',
                        
    'ч' => 'ch',  'ш' => 'sh',  'щ' => 'sch',
                        
    'ь' => '\'',  'ы' => 'y',   'ъ' => '\'',
                        
    'э' => 'e',   'ю' => 'yu',  'я' => 'ya',
            
                        
    'А' => 'A',   'Б' => 'B',   'В' => 'V',
                        
    'Г' => 'G',   'Д' => 'D',   'Е' => 'E',
                        
    'Ё' => 'E',   'Ж' => 'Zh',  'З' => 'Z',
                        
    'И' => 'I',   'Й' => 'Y',   'К' => 'K',
                        
    'Л' => 'L',   'М' => 'M',   'Н' => 'N',
                        
    'О' => 'O',   'П' => 'P',   'Р' => 'R',
                        
    'С' => 'S',   'Т' => 'T',   'У' => 'U',
                        
    'Ф' => 'F',   'Х' => 'H',   'Ц' => 'C',
                        
    'Ч' => 'Ch',  'Ш' => 'Sh',  'Щ' => 'Sch',
                        
    'Ь' => '\'',  'Ы' => 'Y',   'Ъ' => '\'',
                        
    'Э' => 'E',   'Ю' => 'Yu',  'Я' => 'Ya',
                        );
                    return 
    strtr($string$converter);
                    }
                }

                if (!
    function_exists('str2url'))
                {
                    function 
    str2url($zagolovok)
                    {
                        
    $zagolovok rus2translit($zagolovok); // Символы в транслит
                        
    $zagolovok strtolower($zagolovok); // Символы в нижний регистр
                        
    $zagolovok preg_replace('/-/'''$zagolovok); // Удаляем все тире
                        
    $zagolovok preg_replace('~[^-a-z0-9_]+~u''-'$zagolovok); // Заменям все ненужное на тире
                        
    $zagolovok trim($zagolovok"-"); // Удаляем тире в начале и конце

                         
    return $zagolovok
                    }
                }
                
    $adres str2url($zagolovok);

                
    $oInformationsystem_Item->path $adres// Адрес элемента

                /* Метки */

                
    $metki str_replace(', '' '$kluchi); // Удаляем запятые (Иначе будут частью тега)
                
    $aTagsNames explode(' '$metki);

                foreach (
    $aTagsNames as $sTagName)
                {
                    
    $oTag Core_Entity::factory('Tag')->getByName($sTagName); // Доабвляются только теги из базы
                    
    if (!$oTag)
                    {
                        
    // Create new tag
                        
    $oTag Core_Entity::factory('Tag');
                        
    $oTag->name $sTagName;
                        
    $oTag->save();
                    }
                
    $oInformationsystem_Item->add($oTag); // Связываем тег с инфомрационным элементом
                
    }

                
    $oInformationsystem_Item->informationsystem_group_id = !is_null($oInformationsystem_Group->id)
                    ? 
    $oInformationsystem_Group->id 0;

                if (
    strlen($oInformationsystem_Item->name))
                {
                    
    // Save informationsystem item
                    
    $oInformationsystem->add($oInformationsystem_Item);
     
    Последнее редактирование: 5 ноя 2012
  3. sersh

    sersh New Member Пользователи

    Регистрация:
    29 окт 2012
    Сообщения:
    5
    PHP:
    <?php
    ПРОДОЛЖЕНИЕ
                    
    // Проверка на существование файла изображения к элементу
                    // Если изображения нет переходим к следующему элементу
                    
    $photo = @fopen($aItem['enclosure']['url'], "r");
                    if (
    $photo)
                    {

                        if (isset(
    $aItem['enclosure']['url']))
                        {
                            
    $Core_Http Core_Http::instance()
                                ->
    url($aItem['enclosure']['url'])
                                ->
    execute();
        
                            
    // Определяем расширение файла
                            
    $ext Core_File::getExtension($aItem['enclosure']['url']);

                            
    $temp_file tempnam(TMP_DIR"rss") . '.' $ext;
                            
    Core_File::write($temp_file$Core_Http->getBody());
        
                            
    $param = array();
        
                            
    // Путь к файлу-источнику большого изображения;
                            
    $param['large_image_source'] = $temp_file;
        
                            
    $large_image 'information_items_' $oInformationsystem_Item->id '.' $ext;
                            
    $small_image 'small_' $large_image;
        
                            
    // Оригинальное имя файла большого изображения
                            
    $param['large_image_name'] = $large_image;
        
                            
    // Оригинальное имя файла малого изображения
                            
    $param['small_image_name'] = $small_image;
        
                            
    // Путь к создаваемому файлу большого изображения;
                            
    $param['large_image_target'] = $oInformationsystem_Item->getItemPath() . Core_File::convertFileNameToLocalEncoding($large_image);
        
                            
    // Путь к создаваемому файлу малого изображения;
                            
    $param['small_image_target'] = $oInformationsystem_Item->getItemPath() . Core_File::convertFileNameToLocalEncoding($small_image);
        
                            
    // Использовать большое изображение для создания малого
                            
    $param['create_small_image_from_large'] = TRUE;
                            
    $param['watermark_file_path'] = $oInformationsystem->getWatermarkFilePath();
                            
    $param['watermark_position_x'] = $oInformationsystem->watermark_default_position_x;
                            
    $param['watermark_position_y'] = $oInformationsystem->watermark_default_position_y;
                            
    $param['large_image_preserve_aspect_ratio'] = $oInformationsystem->preserve_aspect_ratio;
                            
    $param['small_image_max_width'] = $oInformationsystem->group_image_small_max_width;
                            
    $param['small_image_max_height'] = $oInformationsystem->group_image_small_max_height;
                            
    $param['small_image_watermark'] = $oInformationsystem->watermark_default_use_small_image;
                            
    $param['small_image_preserve_aspect_ratio'] = $param['large_image_preserve_aspect_ratio'];
                            
    $param['large_image_max_width'] = $oInformationsystem->group_image_large_max_width;
                            
    $param['large_image_max_height'] = $oInformationsystem->group_image_large_max_height;
                            
    $param['large_image_watermark'] = $oInformationsystem->watermark_default_use_large_image;

                            
    $oInformationsystem_Item->createDir();
        
                            
    $result Core_File::adminUpload($param);
        
                            if (
    $result['large_image'])
                            {
                                
    $oInformationsystem_Item->image_large $large_image;
                                
    $oInformationsystem_Item->setLargeImageSizes();
                            }
        
                            if (
    $result['small_image'])
                            {
                                
    $oInformationsystem_Item->image_small $small_image;
                                
    $oInformationsystem_Item->setSmallImageSizes();
                            }
        
                            
    $oInformationsystem_Item->save();
        
                            
    Core_File::delete($temp_file);

                            
    $iImported++;
        
                            echo 
    "Элемент <b>/$adres/</b> - импортирован.<br />";
                        }

                    }
                    else
                    {
                        echo 
    "Элемент <b>/$adres/</b> - импортирован <b>(без фото).</b><br />";
                    }

                }

            }
        }
    }
    echo 
    "<b>Проимпортировано $iImported элементов</b>";
    ?>
    В строке браузера вводим: Ссылки недоступны для гостей - жмем Enter
    В результате в корне сайта появится файл import.xml из которого и будут созданы элементы ИС, а в указанной вами ИС появятся элементы.
    Рассортировываем элементы по созданным вручную группам.
    Все.

    Самая частая ошибка - нечитаемый символ в файле импорта (будет указана строка, ищем и исправляем).
    Если у элементов нет фото - значит неправильно прописали адрес в коде или их нет вообще. Берем с сервера файл import.xml и изучаем.
    Все изменения должны быть проведены в файле article_all_1.php т.к. файл import.xml перезаписывается при каждом запуске кода.

    Если есть какие-то вопросы задавайте, постараюсь ответить.
     
    Последнее редактирование: 5 ноя 2012

Поделиться этой страницей