— пока хирург оперирует человека, парсер оперирует его сайт…
В связи с внезапным всплеском интереса к моему парсеру — AftParser пишу эту статью. Люди часто задают мне вопрос — «как пользоваться этим продуктом». Чтож, настало время дать рабочий пример.
Для начала давайте определимся с тем, что мы будем парсить. То есть с тематикой. Если мы собираемся сделать, например, сайт о медицине или докторских, скажем так, «байках», то идем на ЖЖ. Пусть это будет, к примеру, блог med-history
Сбор ссылок
Первым делом нам надо собрать ссылки на материалы с этого блога. Для этого в парсере есть два, весьма годных, инструмента. Парсер карты сайта, и Парсер ссылок.
В чем разница? Парсеру карты сайта надо давать ссылки на файлы sitemap.xml В большинстве сайтов на движках wordpress, joomla, drupal или dle есть карта сайта, а этот инструмент может достать оттуда ссылки и добавить их в список. В большинстве случаев этого парсера достаточно, но, в ЖЖ нет карты сайта или она есть, но я не знаю где она 🙂
Парсер ссылок же работает как поисковый робот. Он переходит по всем внутренним ссылкам сайта и добавляет их в список. Причем чем дольше длится процесс парсинга, тем больше материалов будет добавлено. Недостаток этого метода в том, что он может напарсить кучу мусора и бесполезных ссылок. Впрочем давайте перейдем к делу.
Для того, чтобы собрать ссылки указываем грабберу на главную страницу блога — жертвы. Можно и не на главную, тут разницы нет.
Нажимаем на кнопку старт и видим как наш робот начал свое черное СЕО то есть дело.
Можете сходить покурить или попить чаю. Процесс это не быстрый, но я не буду затягивать т.к. пишу эту статью. Чтобы завершить процесс просто закройте окно и подождите секунду, чтобы ссылки скопировались в общий список.
И так, первая стадия завершена, переходим ко второй.
Фильтрация
В ссылках собранных нами очень много мусора. Мягко говоря. А нам нужны материалы. Именно матералы, а не побочные страницы со всяким мусором. Как правило(всегда) у пути к материалу есть своя маска. Перехдим на главную страницу блога жертвы и наводим мышу на заголовок — ссылку каждого поста. Смотрим что нам показывет хром.
Как мы видим у постов есть маска. Они оканчиваются на .html Быстро проматываем и анализируем список ссылок. Есть ли там страницы с окончанием на .html но не указывающие на пост?
Как мы видим — таких страниц нет. Нам повезло! Но вообще у меня глаз наметан я уже умею анализировать большие объемы текста даже не читая. Такова вот она работа програмиста. Тут многое зависит от умения быстро понять что-же написано в коде или в мануале. Причем на любом языке включая китайский, не приведи вам бог искать пошивку биоса на леново…. Ну так вот. Теперь мы определились с фильтром.
Фильтровать ссылки можно двумя способами: через PHP и используя простой встроенный фильтр.
Преимущество фильтра на PHP в том, что там на ходу можно изменять ссылки, приписывать к ним что-то, например.
Но мы будем использовать простой фильтр т.к. надо отфильтровать лишь .html
Тыкаем «фильтровать» и смотрим выше что у нас получилось. За одно проверяем ссылки, переходя по паре-тройке.
Как мы видим все ОК и мы можем приступать к наглому пиздингу контента из этого источника. Разумеется в рамках культуры я бы советовал вам оставлять ссылку на блог, с которого парсите материалы. Ведь его автор реально старался для своих читателей. Но это оффтоп, а у меня лекция стынет. И так. Чтобы более-менее нормально спарсить материал надо определиться с его разметкой.
Подготовка границ контента
Любой отрезок текста в HTML документе всегда обрамлен в теги. Так было, так есть и так будет. Это значит, что мы можем вырезать этот отрезок текста по верхнему и нижнему тегу-границе. Это принцип работы моего парсера контента.
Для начала нам надо задать одну границу для заголовка и одну границу для контента. Вообще функционал позволяет нам задавать не ограниченное кол-во границ контента. Но мы не задаемся целью спарсить все и вся, а лишь дергаем текст самого материала. И так, давайте приступим.
Сестра, скальпель!
Переходим на один из материалов блога, например сюда — http://med-history.livejournal.com/78826.html и тыкаем в хроме F12 (если у вас жопера или огнелис то там я не знаю сочетания клавиш, короче нам нужны инструменты вебмастера). На заголовке нажимаем «Просмотреть код», вот так:
Мы видим в разметке, что заголовок материала находится между блоками
<h1 class="
и </h1>
Запомните: мы не смотрим на целостность тегов. Нам на это вообще до лампочки. Для нас html документ это просто набор границ. Это как лист бумаги, который мы режем. Поэтому мы можем указать в качестве начала заголовка как обрубок тега, так и комментарий или например русский текст.
К стати. Чтобы было удобно выделять код просто нажмите клавишу F2 в инструментах вебмастера и тогда это будет проще.
Не будем тянуть кота за гениталии и вставим полученные куски разметки в соответствующие поля на форме парсера.
После чего нажимаем «Добавить» и продолжаем.
Теперь нам надо задать границу контента.
Делаем все то-же самое, что и с заголовком, но уже на тексте материала.
Вот у нас верхняя граница (в конце тега article): lj-embed-resizer >
А нижняя просто: </article>
Важно: проверьте границы используя Webmaster Tools. Они должны повторяться на каждой странице блога-жертвы.
Если все в порядке — добавляем.
И так путь пройденый нами был довольно долог, особенно учитывая эту содомию со скриншотами, но это еще не конец. На самом деле все эти действия я уже давно выполняю на автомате. Думаю и вы, разобравшись, сможете делать так-же. Перейдем же непосредственно к формированию материала.
Формирование материала
Тут у нас есть выбор. Доверить формирование материала криворукому скрипту или сделать все самостоятельно. Я настоятельно советую совмещать! оба этих подхода. Что мы с вами сейчас и сделаем. Для начала лениво выставим галочки:
И нажмем кнопку «тестировать», внизу:
Смотрим на результаты тестирования и анализируем.
Тут мы видим одно непотребство, которое надо убрать.
Оно в заголовке. Я подчеркнул, в скриншоте.
Как этот шлак убрать? Очень просто. Для этого у нас есть php и макрос. Просто переходим на редактор макросов и начинаем писать код, попутно его тестируя!
И так. В заголовке надо убрать все, что идет до символа «>» включая сам символ. Для этого пишем такой код:
$title = $this->get_border('fragment_1',$html); // суем содержимое первой границы в переменную
$pos = mb_strpos($title,">"); // узнаем позицию маркера ">"
if($pos !== false) $title = mb_substr($title, $pos+1,mb_strlen($title)-$pos+1); // обрезаем строку + 1 символ ">"
$res .= $this->set_title(trim($title)); // задаем строку как заголовок
Тестируем.
Все чисто.
Теперь к контенту. Тут у нас есть мусорные метки со всякой там группой «вфейсбуке». Делаем так-же.
В данном случае верхним триггером будет слово «PS». Код:
$pos1 = mb_strpos($res,"PS");
if($pos1 !== false) $res = mb_substr($res,0,$pos1-1); // обрезаем строку с начала до - 2 символа после "PS"
После тестирования видим, что все в полном порядке. Теперь мы хотим, чтобы при парсинге материалы с этого сайта попадали в категорию, например, «медицина». Прописываем в теле макроса простую команду: $res .= $this->set_catname("медицина");
Не важно, есть у вас эта категория или нет. Если ее нет — плагин сам ее создаст.
Общий код макроса будет таким:
/*
* Приведение кодировки
* $blog_enc - кодировка страниц блога
* $src_enc - автоматически определенное значение кодировки. Берется из тега <meta> страницы.
* Если значение $src_enc определяется не верно - укажите его самостоятельно.
*/
if($blog_enc != $src_enc) $html = mb_convert_encoding($html, $blog_enc, $src_enc);
$title = $this->get_border('fragment_1',$html);
$pos = mb_strpos($title,">");
if($pos !== false) $title = mb_substr($title, $pos+1,mb_strlen($title)-$pos+1); // обрезаем строку + 1 символ ">"
$res .= $this->set_title(trim($title));
$res .= $this->get_border('fragment_2',$html);
$res = $this->clear_tags_from_trash($res);
$res = $this->remove_a_href($res);
$res .= $this->add_indent();
$res = $this->process_images($res);
$pos1 = mb_strpos($res,"PS");
if($pos1 !== false) $res = mb_substr($res,0,$pos1-1); // обрезаем строку с начала до - 2 символа после "PS"
$res .= $this->set_catname("медицина");
Парсинг
Вы можете спарсить все материалы немедленно, нажав на соответствующую кнопку:
Но это может сильно нагрузить сервер. Советую просто сохранить настройки для отложенного парсинга. К тому-же так вы в любой момент сможете их отредактировать, если что-то пойдет не так.
После сохранения через несколько секунд должен спарситься первый материал. Переходим в записи и смотрим:
И вот он! Все картинки скачаны, все выглядит цивильно и красиво.
Материалы будут добавляться на ваш сайт всякий раз, как кто-то будет посещать его.
Хороше? Отлично! Именно так все и работает. К слову вы можете настроить свой CRON если умеете. Для этого во вкладке плагина «Дополнительно» есть соответствующие пункты, которые смотрите сами.
Точно так-же работает и граббер RSS лент.
К стати! Если вы хотите, чтобы к вашим спарсенным постам автоматически выставлялась картинка — описание то поставьте себе вот этот плагин: Auto Post Thumbnail
Надеюсь эта статья будет вам полезна.
Первое и главное — спасибо за чудесный плагин!
И второе, кто подскажет, почему не работает переводчик на RSS, можете скинуть вариант готовой строки для рус-англ языка?
переводчик от яндекса не работает потому что он глючный, другого переводчика просто нет, если хотите чтобы не глючило там надо у яшки на платный тариф переходить.
Спасибо за ответ! Я уже думал что то сам накосячил
Отличный парсер. Спасибо.
Есть вопрос:
Над кнопкой: «начать парсинг» указано, что каждую секунду публикуется максимум 1 пост.
Вопрос: как сделать, чтобы за 3 секунды один пост?
там все немного по другому работает. У сек — это среднее время, указанное мной для примера, а так он не начнет парсить следующий материал, пока не спарсит предыдущий.
А возможно как то сделать ограничение не более 1 записи в 3 секунды?
День добрый. сразу оговорюсь что я не программист.
подскажите как убрать тег и из такой строки [title]НУЖНЫЙ ТЕКСТ1НУЖНЫЙ ТЕКСТ2[/title]
мне бы его желательно не убрать, а заменить на пустоту.
пробовал
$res .= $this->set_title($this->get_border(«fragment_1»,$html));
$res .= $this->preg_replace(«//»,»»,$res);
пишет не верный макрос.
вот так
все теги повырезало;(
сделал скриншот http://i102.fastpic.ru/big/2018/0214/37/9032cb54bf14534e44c40126d1a0e937.png
попробуйте str_replace
спасибо, сам разобрался;)
проблема с парсингом возникла. делаю так: $name_arr = $this->get_recurrence_border(«hed»,$html); проверяю массив — в массиве элементов в два раза больше, чем есть на самом деле, то есть сайт парсится дважды. как исправить? заранее спасибо))
юзайте функцию array_unique на $name_arr
спасибо) сработало
Здравствуйте. Как парсить дополнительные поля для wordpres?
добрый день!
Парсю сайт один в табличной верстке , у них нет h1 … указываю класс вручную а мне пишет вот такое Ошибка!
Селектор заголовка не указан
Как решить трабл ? спасибо
с таблицами всегда были проблемы, попробуйте парсить по границам, хотя и там не проще, но может получиться зацепиться за что-то
Доброй ночи.
Подскажите по поподробней что нужно править в файле publisher.php чтобы парсилось в определённые статьи.
С уважением Алекс.
изменйте метод add_node
Доброе время суток!
А можно ли как-то парсить мета данные тайтл и дескрипшен?
без доделок нельзя
Пишет ошибку при тестировании — селектор заголовка не указан, хотя ставлю h1… пробовал и …
попробуйте другие селекторы подобрать
Пицца с грибамии и колбасой
Не цепляет по селектору h1. Парсил у них 3 месяца, а потом в один и тот же день в какой-то момент перестал работать парсер. IP динамический. Пробовал с другого компа на работе, тоже самое. Другой сайт вроде парсится. Как решить проблему ? Это какая-то защита от парсинга на сайте доноре включилась ?
возможно селектор заголовка изменился, попробуйтеи вы его изменить. или настроить парсинг по границам.
Можете подсказать какой в этом случае будет селектор для названия ?
Айсинг для росписи пряников
приветствую! После 4х месяцев отличной работы, парсер перестал работать. Настройки не менялись. Выдается ошибка добавления материала. Менял селекторы — не помогло, пишет селектор не определен. Также не работает парсинг с другого компа. Попробовал спарсить другой сайт — все работает. Что может быть? Мог ли сайт донор включить защиту от парсинга? Как решить проблему ?
сайт-донор мог поставить клаудфлейр… попробуйте взять прокси и спарсить через прокси, там есть же поле для проксюка. Если нет скачайте актуальную версию и с ней попробуйте, предварительно забекапив сайт и базу!!!
Спасибо за ответ ! Буду пробовать.
Ещё хотел добавить, может это как-то поможет понять. Тестер вы дает такую информацию:
[————- проход_0—————]
[title]Проверка браузера, пожалуйста, подождите…[/title]
[————- /проход_0—————]
Что ещё за проверка браузера ? Нужно подождать или это висяк уже ?
Всем привет. Есть ли возможность получить URL страницы с которой парсинг идёт? У меня необходимость сохранить последнюю часть урла(slug), на доноре они то капсом написаны, то вовсе отличаются.
да можно $this->current_url
У вас косяк в последней версии плагина.
Не формирует границы в php окне при указании границ для парсинга.
1 час не мог понять что не так
Добавьте для скачивания несколько версий во избежании различных проблем.
Плагин отличный 40 к статей парсит спокойно.
ну там бывают иногда такие ситуации. Можете по подробнее описать суть проблемы? Ну что вы по шагам делали и так далее
Добрый день. А возможно ли как нибудь увеличить скорость парсинга? Сейчас он парсит со скоростью 1 материал за 3-4 секунды — скорость одинакова что на локальном пк с денвером, что на шаред хостинге, что на vps. На локальном пк парсил с 3 джи свистком и через оптоволокно 100мбит/с — скорость не менялась. Заранее спасибо.
нет нельзя, если нужен скоростной парсер такого рода лучше посмотрите в сторону десктопных решений вроде CondentDownloader или Xparser
Все выглядит очень вкусно, но я даже не могу его установить, пишет -ссылка устарела. PHP меняла на 5,6 и на 7, но проблема не исчезает. Можно дополнить статью подробностями установки для таких ламеров, как я?
Привет, ниразу не программист, юзаю макрос на перевод $res .= $this->get_translation($res, $fromlg (eng), $tolg(ru), $key); , выбивает ошибку. Что я делаю не так?
надо заменить $fromlg на «en» $tolg на «ru» и $key на ваш ключ яндекс переводчика. Там в документации все есть. Но оно все равно может не работать, потому что это яндекс переводчик.