Архив

Архив рубрики «Контент&»

Создание парсера под сайт на основе Express Parse

В основе плагина Express Parse лежит очень гибкий механизм парсинга, не привязанный к программной реализации. Его работа построена на перечне правил поиска текста и цепочек фильтраций, которые находятся в отдельных файлах. Сейчас мы рассмотрим пример, который поможет Вам понять, как можно создать парсер под определенный сайт на основе плагина Express Parse. Однако, для этого Вам необходимо иметь хоть малейшее представление о регулярных выражениях и XPath.

Для начала определимся с сайтом, который мы будем парсить. Я выбрал для примера сайт www.rusarticles.com с бесплатными статьями. Сайт был выбран, так как предоставляет статьи бесплатно, но в любом случае не забывайте об авторских правах и по возможности выставляйте ссылки на источники статей. Обратите внимание, что нужно использовать последние версии BlogBot Ultimate (3.0.5) и Express Parse (1.5).

Шаг первый

Для начала нужно добавить в список сервисов наш сайт. В директории плагина (/plugins/expressparse) есть файл services.txt, в котором храниться список сервисов для парсинга. Открываем этот файл на редактирование обычным текстовым редактором (не нужно использовать MS Word или Writer, рекомендую использовать Notepad++). Добавляем в него строчку такого типа:

rus,RusArticles,http://www.google.com/search?hl=ru&q={QUERY}+site:rusarticles.com&lr=lang_ru

Здесь rus – это идентификатор сервиса (2-4 символа), не должен повторяться, RusArticles – название сервиса (не должен содержать запятых), далее – строка запроса в Google для нашего сайта. Эти три поля должны идти в одну строку и быть разделены запятыми. Если Вы создаете парсер для другого сайта, вам нужно будет не забыть изменить в строке запроса после site: адрес сайта. Для англоязычных сайтов строка запроса может выглядеть так:

http://www.google.com/search?hl=en&q={QUERY}+site:articlesbase.com

Сохранив файл, зайдем в BlogBot на страницу настроек плагина. В списке сервисов появился сайт RusArticles.

Шаг второй

Теперь приступим к написанию правил. Создаем в директории /plugins/expressparse/rules файл с названием домена и расширением txt. У нас это будет .rusarticles.com.txt. Точка впереди означает, что под это правило подходят все сабдомены домена (напр., www.rusarticles.com). Если нужно создать правило для сабдомена, указываем его явно, например, правила sub.domain.ru.txt не будут распространяться на весь домен domain.ru, а только на сабдомен sub.domain.ru. Открываем сайт, который мы будем парсить и переходим на первую попавшуюся статью. Видим что ссылки на статьи имеют вид:

/category_alias/article_alias-article_id.html

В созданном файле пишем следующее:

LocationMatch /-\\d+\\.html$/

Это означает, что правила следующие ниже, будут применены к страницам, адрес которых заканчивается несколькими цифрами, после которых следует .html. В общем случае можно написать так:

LocationMatch /./

Под это условие подходят все страницы. Как Вы, наверное, заметили здесь использованы регулярные выражения. Символ «$» означает конец строки, «\d+» — одна и более цифра, символ «\» идёт дважды подряд, т. к. первый слэш экранирует второй. В правилах следует всегда экранировать слэши и пробелы. Еще пара примеров:

LocationMatch /page=\\d+/

Это условие подразумевает страницы сайта без ЧПУ, когда ID статей указаны в числовом виде.

LocationMatch /\\/category\\/video\\//

Это условие подразумевает статьи из категории video. Директив LocationMatch может быть сколько угодно в пределах файла, и её условие распространяется на все директивы после неё и до конца файла или до следующего LocationMatch. Файл правил всегда должен начинаться с этой директивы.

Далее нам нужно определить, что мы будем «грабить» со страницы. Открываем исходный код страницы, либо пользуемся расширением FireBug для Firefox для просмотра дерева элементов. Видим, что статья заключена в тэг div с атрибутом . Благодаря этому мы можем выбрать часть HTML со страницы с помощью XPath. Для этого используем директиву Filter. Для начала преобразуем текст в объект DOM.

Filter TextToDOM @body

Здесь мы указываем имя фильтра и к чему он будет примерен. Изначально исходный текст страницы храниться в переменной @body. После применения фильтра будет создана переменная dom, в которой и будет находиться наш DOM-объект. Из этого объекта выбираем часть:

Filter SearchDOM dom WithParams path=//div[attribute::class="article_cnt\ KonaBody"] name=body html=true

Здесь после ключевого слова WithParams идет список параметров фильтра. Параметры разделены пробелами. Если в значении параметра будет пробел или символ «\», они экранируются символом «\». Переносов на новую строку быть не должно. Это касается всех директив. В параметре path мы передаем выражение XPath, в параметре name – имя переменной, в которую будет помещен результат, html=true означает, что нам нужно сохранить верстку. Можно также использовать фильтр Search, который использует регулярные выражения. Анализируя исходный код страницы, мы видим, что нужная нам часть находится между тэгами и, поэтому, убедившись, что эти тэги более не встречаются, пишем:

Filter Search @body WithParams pattern=#<index>(.*)</index>#Uis name=body index=1 all=false

Здесь параметр name снова означает имя переменной для результата, index указывает какое из совпадений следует выбрать 0 – всё, 1 – то, что подходит под выражение заключенное в первые скобки и т. д. Параметр all задает тип поиска true – искать все вхождения, false – только первое.

Теперь у нас есть кусок текста с нашей статьей. Однако, в ней могут встретиться левые ссылки или скрипты, мы можем вырезать это безобразие. Для этого мы используем фильтр Replace, указывая, что ищем с помощью регулярного выражения, заданного параметром search. Замена передается в параметере replace, который по умолчанию равен пустой строке, и поэтому мы его не указываем.

Filter Replace body WithParams regexp=true search=#<script.*</script>#Uis
Filter Replace body WithParams regexp=true search=#<a.*>#Uis
Filter Replace body WithParams regexp=false search=</a>

Готово! Еще нам нужен заголовок. Без него статья не будет добавлена. Разработчики сайта не стали добавлять в заголовок страницы ничего, кроме названия статьи, поэтому название можно взять оттуда. Снова используем фильтр Search:

Filter Search body WithParams pattern=#<title>(.*)</title>#Uis index=1 name=title all=false

Можно также использовать SearchDOM:

Filter SearchDOM dom WithParams path=//title name=title

К сожалению, на сайте RusArticle нет картинок. Но если они там когда-нибудь появятся, их можно будет получить с помощью фильтра DownloadImages, который скачает картинки и заменит пути к ним в тексте. Класс картинкам можно присвоить параметром imgclass.

Filter DownloadImages body WithParams imgclass=alignleft

И финальный аккорд: нам нужно сбалансировать теги (чтобы не было закрывающих без открывающих или наоборот) и удалить всякий мусор из статьи. Для этого у нас есть фильтр WpFormat, который форматирует статью в соответствии с общепринятыми нормами, а также добавляет метку <!—more—>, чтобы выделить превью.

Filter WpFormat body

Правда у последнего фильтра есть один недостаток, он удаляет из текста списки, таблицы и другие подобные элементы, поэтому, если Вы уверены, что в статье нет того, что могло бы исказить её верстку, можно обойтись без него. Данный фильтр полезно опустить, если вы парсите каталоги товаров, анкеты пользователей или другой специфический контент. Соберем все в одну кучу и получим:

LocationMatch /-\\d+\\.html$/
Filter TextToDOM @body
Filter SearchDOM dom WithParams path=//div[attribute::class="article_cnt\ KonaBody"] name=body html=true
Filter Replace body WithParams regexp=true search=#<script.*</script>#Uis
Filter Replace body WithParams regexp=true search=#<a.*>#Uis
Filter Replace body WithParams regexp=false search=</a>
Filter DownloadImages body WithParams imgclass=alignleft
Filter WpFormat body
Filter SearchDOM dom WithParams path=//title name=title

Всего 9 строк! Ну разве не прелесть? Теперь было бы неплохо проверить как это будет работать.

Шаг третий

Возвращаемся в BlogBot на страницу плагина, задаем пару ключевиков (пока для теста, дальше – больше). Сохраняем настройки, отметив галочкой только наш сервис RusArticle и опцию «Публиковать в контент BlogBot». Остальные опции отключаем. Переходим на вкладку «Прогресс». Тут у нас должно быть ровно столько ссылок, сколько ключевых слов мы указали. Если их больше, то скорее всего это ссылки, оставшиеся после предыдущих запусков плагина. В таком случае нужно сбросить прогресс. Если у Вас есть еще плагины, кроме ExpressParse, их желательно деактивировать, в свою очередь, ExpressParse должен быть активирован. Открываем в браузере ссылку http://mybb.ru/thread_pl.php?debug_mode&v, где mybb.ru – это домен, на котором находится Ваш BlogBot. На открытой странице должен отобразиться ход работы плагина.

Wed, 02 Jun 10 14:31:21 +0300 : Plugin started: Express Parse
Wed, 02 Jun 10 14:31:21 +0300 : Sending request: http://www.google.com/search?hl=ru&amp;q=%D0%BF%D0%BE%D0%BB%D0%B8%D1%82%D0%B8%D0%BA%D0%B0+site:rusarticles.com&amp;lr=lang_ru
Wed, 02 Jun 10 14:31:22 +0300 : Connection done
Wed, 02 Jun 10 14:31:23 +0300 : Response: HTTP/1.1 200 OK

Возвращаемся к прогрессу и видим новые ссылки. Часть из них – это ссылки на сайт rusarticles.com, остальные должны быть ссылками на Google на следующие страницы поиска. Если там оказались не те ссылки, которые мы ожидали, то, вероятно, Вы сделали что-то не так на первом шаге. Обновляем страницу с ходом выполнения работы. Теперь плагин будет обходить найденные страницы и применять к ним наши правила.

Wed, 02 Jun 10 15:06:40 +0300 : Plugin started: Express Parse
Wed, 02 Jun 10 15:06:40 +0300 : Sending request: http://www.rusarticles.com/raznoe-statya/sootnoshenie-prava-i-politiki-513468.html
Wed, 02 Jun 10 15:06:45 +0300 : Connection done
Wed, 02 Jun 10 15:06:46 +0300 : Response: HTTP/1.1 200 OK
Wed, 02 Jun 10 15:06:46 +0300 : Added post: `Соотношение Права И Политики` to category `политика`
Wed, 02 Jun 10 15:06:46 +0300 : Can't find rule for http://www.rusarticles.com/privacy-policy
Wed, 02 Jun 10 15:06:46 +0300 : Sending request: http://www.rusarticles.com/politika-statya/25-letnij-pacient-umer-v-psixushke-2196867.html
Wed, 02 Jun 10 15:06:46 +0300 : Connection done
Wed, 02 Jun 10 15:06:47 +0300 : Response: HTTP/1.1 200 OK
Wed, 02 Jun 10 15:06:47 +0300 : Added post: `25-Летний Пациент Умер В Психушке` to category `политика`

Судя по этому логу мы видим, что плагин нашел две статьи. Эти статьи теперь находятся в разделе «Контент». Ссылку http://www.rusarticles.com/privacy-policy он не обработал, т. к. она не подошла под условие LocationMatch. Если в результате работы статьи не были найдены, то Вам следует искать ошибки в правилах.

Справка по директивам

Коротко опишу директивы и фильтры, которые можно применять в правилах.

LocationMatch <ereg>
Определяет условие, по которому отрабатывает группа директив, следующая далее. Условие срабатывает, когда адрес страницы подходит под регулярное выражение ereg.
Filter <filter_name> <field1> [field2 […]] [WithParams <key>=<value> [<key>=<value> […]]]
Применяет фильтр filter_name к переменным field1…fieldN с параметрами, указанными после ключевого слова WithParams. В результате работы фильтра может измениться содержимое переменных, либо появиться новые.
Skip [NRules]
Пропускает NRules директив, по умодчанию NRules равно 1.
Condition <field1> [Not] <cond> [N]
Пропускает N директив, если переменная field1 не подходит под регулярное выражение cond или если подходит и указано ключевое слово Not. По умолчанию N равно 1.

Список фильтров, которые можно использовать следующий:

ArticleAnalyzer
Фильтр для поиска статьи по умолчанию. Может находить статьи на страницах почти с любой версткой. Однако иногда может выдавать не совсем «чистые» статьи.
Параметры фильтра
Название Описание По умолчанию
preserveImages Сохранять картинки или нет. Может быть true или false. true
preserveLinks Сохранять ссылки или нет. Может быть true или false. FALSE
metaPrefix Префикс для имен переменных, которые будут содержать мета-данные страницы. без префикса
encoding Кодировка страницы. utf-8
resultMinLength Минимальная длина статьи. Если длина статьи будет меньше этого параметра, статья будет считаться не найденной. 600
storeMeta Сохранять мету или нет. Может быть true или false. true
ArticleAnalyzer2 и ArticleAnalyzer3
По функциональной нагрузке и списку параметров аналогичны фильтру ArticleAnalyzer. Различаются лишь результатами работы. Иногда полезно применить последовательно все три фильтра. Если статья не была найдена одним фильтром, то отрабатывает следующий.
ConvertEncoding
Фильтр для преобразования текста из одной кодировки в другую.
Параметры фильтра
Название Описание По умолчанию
from Исходная кодировка. Параметр обязателен.
to Результирующая кодировка. Параметр обязателен.
CyrillicToEntities
Преобразует кириллические символы в HTML-сущности и наоборот. Могут быть использованы кодировки utf-8, cp1251 и htmlentities.
Параметры фильтра
Название Описание По умолчанию
from Исходная кодировка. utf-8
to Результирующая кодировка. htmlentities
DownloadImages
Загружает картинки, найденные в тексте и заменяет пути к ним.
Параметры фильтра
Название Описание По умолчанию
name Имя переменной, в которую будут записаны имена загруженных картинок. image
storage путь к директории, в которой будут сохранены картинки ./images
minwidth Минимальный размер картинки по ширине, которую можно загружать. 100
minheight Минимальный размер картинки по высоте, которую можно загружать. 100
cut Если указано true, то картинки, которые не были загружены, будут удалены из текста. true
Remove
Удаляет переменные, к которым применён фильтр. Если задан параметр pattern, то будут удалены переменные, подходящие под регулярное выражение, заданное этим параметром.
Replace
Производит замену текста.
Параметры фильтра
Название Описание По умолчанию
search Искомая подстрока или регулярное выражение. Параметр обязателен.
replace Замена. пустая строка
regexp Определяет является ли параметр search регулярным выражением. FALSE
Rewriter
Производит рерайт текста. При использовании фильтра следует учесть, что он весьма ресурсоёмкий.
Search
Производит поиск подстрок в тексте.
Параметры фильтра
Название Описание По умолчанию
pattern Регулярное выражение для поиска. Параметр обязателен.
name Имя переменной, в которую будет записан результат. data
index Указывает какое из совпадений следует выбрать 0 – то, что подходит под всё выражение, 1 – то, что подходит под выражение заключенное в первые скобки и т. д. 0
all Искать все совпадения (true) или только первое (false). true
prefix Строка, которая будет добавлена к каждому результату слева. пустая строка
postfix Строка, которая будет добавлена к каждому результату справа. пустая строка
SearchDOM
Производит поиск в дереве элементов HTML.
Параметры фильтра
Название Описание По умолчанию
path Выражение XPath, указывающее на элементы. Параметр обязателен.
name Имя переменной, в которую будет записан результат. data
prefix Строка, которая будет добавлена к каждому результату слева. пустая строка
postfix Строка, которая будет добавлена к каждому результату справа. пустая строка
html Если равен true, HTML-разметка будет сохранена, иначе результатом будет простой текст. FALSE
Synonym
Производит синонимизацию текста. При использовании фильтра следует учесть, что он весьма ресурсоёмкий.
TextToDOM
Создает DOM-объект из HTML-текста.
Параметры фильтра
Название Описание По умолчанию
encoding Кодировка текста. utf-8
useEntities Конвертировать кириллицу в сущности перед созданием объекта или нет. В некоторых случаях без этой операции кириллица может быть искажена. true
name Имя переменной для результата. dom
WpFormat
Форматирует текст, балансируя теги и удаляя мусор. Добавляет метку <!—more—>. После первого абзаца.
Параметры фильтра
Название Описание По умолчанию
thumbMinSize Минимальный размер превью. Если в первом параграфе будет меньше символов, чем задано параметром, то метка <!—more—> устанавливается после второго или третьего и т.д., пока не наберется достаточное количество текста. 300
paragrahpMinSize Минимальный размер параграфа. Если количество символов в параграфе меньше, чем задано параметром, параграф удаляется. 50

Кое-что о переменных

Изначально доступны следующие переменные: @body – HTML страницы, @current-url – текущий URL и переменные с именами, соответствующими именам HTTP-заголовков ответа и начинающихся с символа «%». Одновременно могут существовать несколько переменных с одинаковым именем, в таком случае, фильтр применяется к каждой из них.

Переменные, кроме указания по имени, могут быть указаны с помощю маски:

Нотация Значение
* Все переменные.
^pattern Переменные, начинающиеся на pattern.
?pattern Переменные, содержащие в имени pattern.

Заключение

Это все, что я могу рассказать о создании парсеров с помощью ExpressParse. Подробно о регулярных выражениях Вы можете почитать на сайте php.net, а справку по XPath можно получить на сайте w3schools.com. Удачи в начинаниях!

P.S. Если вам никак не удается написать правила для выбранного вами сайта, обратитесь к нам и мы составим его за 5$.

Popularity: 4%

BlogBot, Контент, Новости, Руководства

BlogBot и контент на английском языке. Обновление 2.0.6.

Сегодня выпустили обновление BlogBot 2.0.6, которое позволит делать сплоги на английском языке. По сути, вы уже и раньше могли парсить английский контент, вводя ключевики на английском, но раньше приходилось лезть в настройки блога, чтобы переключить язык, и мириться с некоторыми мелочами, а многие, наверное, даже не знали, что так можно делать.

english-content

Само обновление, как обычно, бесплатное, но к обновлению идет платное дополнение. Это словарь английских синонимов на 58 000 слов с 3 – 5 заменами на одно слово. Не могу сказать, что качество словаря на высшем уровне, но приемлемое, насколько это вообще возможно проделать с английскими синонимами.

Стоимость словаря – 20$. Заказать словарь можно, как обычно, переведя деньги с кодом протекции и указанием в примечаниях за что они.

Да, чуть не забыл. Пример сайта с английским контентом: http://dekorstone.org.ua.

Popularity: 2%

BlogBot, Контент

Делаем лицо смайликом и начинаем рерайтить

В рамках конкурса: «Из блога слова не выкинешь».

Часто читая форумы, замечаю, что люди иногда задают пару вопросов: что такое рерайт и какого качества он должен быть, чтобы поисковики считали его за уникальный текст?

Начну сразу с определения. Рерайт (Rewrite) – частичная или комплексная переработка текстов сайта, где структура и смысл остаются прежними, а лексика и визуальное оформление изменяется.

В общем, вспоминаем школу, уроки русского языка и такой «веселый» метод оценки знаний, как изложение. Вот – это и есть чистой воды рерайт. Никогда не любил данный вид контроля и обычно разрисовывал поля тетрадки, расставляя всевозможные смайлики, делая вид, что думаю, пока учительница стояла за спиной, и нельзя было пользоваться шпорами.

Теперь о том, насколько сильно нужно рерайтить статью, чтобы она сошла за уникальную у поисковика. Тут все просто, чем сильнее обработка, тем лучше. Простая замена текста синонимами не будет хорошим рерайтом, потому что при читабельном тексте процент замены будет весьма маленьким, примерно, 10%. Если замена будет в пределах 20-40%, то текст будет уже или нечитабельным, или весьма смешным, а комментарии посетителей будут еще смешнее. 🙂 Поэтому раз уж вы обрабатываете текст вручную, то не лишним будет поменять предложения/абзацы местами, но так, чтобы текст остался согласованным; вставить фразеологические обороты, вводные и обязательно ключевые слова, сократить или, наоборот, расширить абзацы.

Ну и напоследок… Если кто-то из вас считает, что рерайт – это плохо, то могу вас заверить, что процентов 60, из того что вам попадается на глаза – это полный или частичный рерайт: новости, статьи, книги, курсовые, диссертации :). Или взять любое событие, например: «Футболки со смайликом стали самыми продаваемыми в 2008 году». Каждое информационное агентство обсосет это событие по-своему, но от этого купленных футболок меньше не станет.

Спонсор конкурса: Stimul Cash — лучшая партнерка рунета

Popularity: 1%

Акции, Контент ,

Формируйте заголовок к посту до и после его написания

Если признаться честно, то я сам всегда сначала придумываю заголовок, и только после этого приступаю к написанию поста, статьи и пр. Согласитесь, что так легче направить мысли в нужное русло!

Но этот метод не всегда оправдывает ожидания. Почему? По двум причинам.

Прежде всего, потому, что данный метод заставляет вас пренебрегать заголовком к посту, который является наиболее важным, что бы вы не писали. Люди, в первую очередь, читают заголовками и только, если они их заинтересовали, переходят к телу поста. Если вы запишите его быстро и перейдете к посту, то все ваше внимание и энергия будет направлена на тело поста.

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

Вторая ошибка заключается в том, что люди сперва формируют заголовок, не будучи уверенными, что будет в его содержании. В таких случаях очень часто заголовки не отражают суть самого поста.

Решение этих проблем как всегда очень простое: формируйте заголовки до и обязательно после написания поста. Прочтите несколько раз пост еще раз, выделите одну главную мысль. Возможно, это будет идеальным заголовком вашего опуса.

Popularity: 1%

Контент