xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Парсинг списков

Опубликовано в

В Parser-е появилась возможность парсить контент не имеющего своих отдельных страниц и выводящийся в виде списков. Например это могут быть комментарии, позиции прайса, фотографии в галерее и т.п.

Для парсинга списков нужно в разделе Дополнительные настройки включить Режим списка и в поле Элементы списка написать код, который вернёт массив с элементами списка:

Дополнительные настройки задания

После этого при наполнении полей станут доступны две новых переменных — $doc_element и $element_html.

Пример парсинга комментариев со страницы http://php.net/manual/ru/function.strpos.php:

Элементы списка:

$elements = array();
foreach ($doc->find('#allnotes .note') as $element) {
  $elements[] = pq($element)->htmlOuter();
}
return $elements;

Содержимое:

return array(
  'value' => $doc_element->find('.html')->html(),
  'format' => 'filtered_html',
);

Имя:

return $doc_element->find('.user')->text();

Не забудьте запустить update.php после обновления модуля.

Написанное актуально для Parser 2
Похожие записи

Комментарии RSS

круто! а page_key для них поддерживается? (в качестве ключей массива, напримэр?)

пока нет, в планах
да

page_key - что это и как использовать?
у меня получается список по 20 комментов на странице.
С одной страницы на одну прекрасно вставляется. а вот ещё 20 с другого урла в туже ноду(nid) - нет.
Сейчас понял и ошибка на это показывает что $element_html = $elements[$context['sandbox']['element']];
$context['sandbox']['element'] - продолжает счетчик 20...
а на новой странице он же опять идет от 0 до 19
Подскажите как это подправить?

page_key это старое название remote_id

попробуйте после $context['sandbox']['progress']++; вставить:

$context['sandbox']['element'] = NULL;

Спасибо. Работает!

Отработало 3 минуты - Создано сущностей: 1096
потом вдруг бах - Notice: Undefined variable: doc_element в функции eval() (строка 1 в файле /sites/all/modules/parser/parser.module(618) : eval()'d code).
Понимаю что в - "Код проверки для дальнейшего парсинга страницы" не появилась переменная $doc_element - то есть там лучше пользоваться $doc? сделал так:

if(!$doc_element) {
  return FALSE;
}
if ($doc->find('#id .class')->length()) {
  return TRUE;
}

если нет элементов для парсинга, то код проверки должен возвращать false

Пытаюсь понять понять как работает парсинг списков.
Внимательно ознакомилась со всеми комментариями из темы http://xandeadx.ru/blog/drupal/399#comment-9844 - не помогает. Мое предположение о том, что возвращаемый в поле "Элементы списка" массив обходится, и на каждый элемент создается сущность, не подтверждается.
Пытаюсь парсить список в field collection, т.е. по моим представлениям на каждый элемент списка должен создаваться field collection item. Элемент коллекции создается и привязывается к родительской сущности (созданной в другом задании) корректно, но только один - первый из массива, остальные элементы массива игнорируются.
Ваш комментарий из вышеуказанной темы: "в одном задании создавайте сущность field collection, в другом связывайте её с нодой" наталкивает меня на мысль о том, что я не совсем верно понимаю механизм работы модуля. Поясните, пожалуйста, как можно field collection создать в одном задании, а связать с нодой в другом, если поле Host entity является обязательным для заполнения в задании, в котором создается элемент коллекции. И как корректно спарсить контент, расположенный на одной странице в field collection?

Мое предположение о том, что возвращаемый в поле "Элементы списка" массив обходится, и на каждый элемент создается сущность, не подтверждается.

именно так и работает

xandeadx, не подскажешь по phpQuery?

Есть код:

<div class="comments">
  <div class="comment id1">
    <p>Text 1</p>
  </div>
  <div class="comment id2">
    <p>Text 2</p>
  </div>
</div>

Если я делаю так:

$elements = array();
 foreach ($doc->find('.comments .comment') as $element) {
   $elements[] = pq($element)->html();
 }
 return $elements;

То получаю:

array(
 [0] => '<p>Text 1</p>',
 [1] => '<p>Text 2</p>'
)

Т.е. html() выдирает только код, располагающийся внутри .comment, а мне нужно, чтобы получилось так:
array(
 [0] =>   <div class="comment id1">
    <p>Text 1</p>
  </div>',
 [1] => '<div class="comment id2">
    <p>Text 2</p>
  </div>'
)

->htmlOuter()

Спасибо!

Подскажите как парсить комментарии. Спарсил материалы, создал задание для парсинга комментариев к этим материалам, в поле "Элементы списка" получаю массив комментариев с исходной страницы, в поле "Remote id" указываю id материала на исходном сайте. В поле "Тема" указываю элемент списка:

$doc_element->find('strong[itemprop="name"]')->text();

Комментарий добавляется, но только первый. Подскажите как парсить чтобы добавлялись все комментарии из массива в поле "Элементы списка"?

видимо в элементах списка возвращаете только один комментарий

Проблема в поле "Remote id", для комментариев туда подставляется id материала и если в поле парсинга указать именно id материала, то парсится только первый комментарий, а остальные игнорируются. Если же при парсинге комментариев в "Remote id" писать id комментария, то парсятся все комментарии, но при повторном запуске все комментарии добавляются вновь (дублируются). Что нужно писать в "Remote id" для корректной работы?

id комментария

Тогда при повторном запуске парсера комментарии дублиются, в результатах работы парсера в поле "Remote id" для записей стоит id материала (видимо парсер сам его проставляет), но соответствие id комментария почему-то не проверяется и создаётся новый комментарий с тем же содержимым.

Если в поле "Remote id" вставить return 123;, то парсятся все элементы массива "Элементы списка" (в моём случае комментарии), но при повторном запуске они вновь добавляются как новые комментарии.

что-то не так делаете

При парсенге списков в материалы всё работает нормально, поле "Remote id" записывается корректно. Но при создании комментариев к материалу из списка парсер всем создаваемым комментариям прописывает "Remote id" в виде id родительской статьи. Поэтому комментарии дублируются при повторном запуске парсера. Скрин результатов работы http://joxi.ru/J2b9v70cyqlZm6. Думаю ошибка в алгоритме создания комментариев из списка.

модуль самостоятельно remote id не прописывает, про "родительские статьи" он ничего не знает

Мой косяк: в при расчете одного из полей назвал переменную $remote_id - она затирала значение, вычисленное в поле выше.

Как получить доступ к порядковому номеру элемента списка при парсинге?

$context['sandbox']['element']

Спасибо! То что надо!

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании