Допилил до более-менее рабочего состояния вторую версию парсера. Основные отличия:
- Парсить можно в любые сущности зарегистрированные на сайте — ноды, термины, пользователи, комментарии, товары и т.д.
- Работа с сущностями ведётся с помощью Entity metadata wrappers.
- Поддержка всех, доступных для записи, свойств сущности — автор, статус и т.п.
- Все файлы, скачанные парсером, сохраняются в кэше (
public://parser_cache
) и при повторном парсинге берутся из него.
Модуль не совместим с первой версией, поэтому перед установкой анинсталим её, удаляем папку с модулем и устанавливаем вторую версию.
Прямая ссылка на скачку последнего снапшота Parser 2.
Если отписываете о найденных багах, то обязательно прикладывайте экспорт задания.
Написанное актуально для
Drupal 7
Похожие записи
- Модуль Parser — парсинг сайтов
- Модуль EAV Field — хранение большого числа характеристик сущности в одном поле
- Модуль Background Queue — выполнение всей очереди в фоне
- Модуль Commerce Fast Ajax Add to Cart — ajax кнопка "Добавить в корзину" без кэширования формы
- Модуль Block Visibility by Vocabulary — вывод блока только на страницах терминов определённого словаря
Комментарии
Нужен совет:
при парсинге получаю PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '6222' for key 'PRIMARY'
в базе смотрел нод с таким nid нет то есть почему она возникает?
Почему так происходит не понимаю.
Не знаю глупый вопрос или нет, но задать хочется:
Когда ждать сиё чудо для Drupal 8!? А то и темы коммерческие уже появляются.
Это очень сложно? А то у меня есть простенькие сайтики ещё на 5-ке :-)
Вот и наконец то решился их перенести так уж на 8-ку! :-)
как будут задачи на парсинг под восьмёрку, тогда и ждать
Александр, большая человеческая просьба!
Как можно обнаружить что парсер берет не тот entity id. уже дня 4 не приходит решение.
при парсинге получаю PDOException: SQLSTATE[23000]:
Integrity constraint violation: 1062 Duplicate entry '6222' for key 'PRIMARY'
Я удалял ноды через Content-> хотя есть функция rollback для уже напарсеных в самом парсере. Может в этом причина что сбился счетчик, хотя брать его парсер должен из базы,
может есть путь debuginga, или намек где копать? Может бывает такое, когда я $page_url вписываю как Remote_id
Ваш опыт профессионала очень ценен и я готов перечислить сумму для развития, Спасибо
я не знаю причину появления ошибки
Подскажите, несколько лет назад были спарсены статьи с одного сайта, в режиме админа видна ссылка на источник, а для анонима она не видна.
1. Задача минимум. Как сделать эту ссылку на источник материала видимой для анонимов?
2. Задача максимум. Как сделать эту ссылку видимой для анонимов и при этом добавить к ней атрибут "rel=nofollow" и чтобы ссылка ссылалась на некий скрипт (модуль) на моём сайте (т.е. для поисковых ботов была внутренней, а не внешней), а уже скрипт бы её перебрасывал через анонимайзер на страницу источник материала?
Спасибо.
получите url с помощью _parser_get_url_by_entity_id()
выведите url в своём node.tpl.php
Решение: свой Rules который пересохранял ноду - получалось реально дубль пытался сохранить, хотя в моем понимании это не один и тот же момент и ошибки быть не должно.
Была ошибка: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '***' for key 'PRIMARY'
Код для поля изображения, проверяющий загружаемые изображения на предмет их наличия на нашем севере.
То есть позволяет избавиться от дубликатов изображений.
Логика работы:
1) Загружаем в кеш проверяемое изображение.
2) Ищем в указанной папке на нашем сервере такой же файл путем сравнения md5 хешей.
3) Если находим дубль, находим его идентификатор (FID)
4) Передаем FID существующего файла.
Александ, а как можно создать-клонировать parser через php со своими изменениями. Пытался поменять jid на новый и сохранить через entity_save не сохраняет, и нового в списке не появляется. entity_create выдает ошибку. по функциям не нашел?
смотрите parser_install() в parser.install
Ну никак не могу получить дату )
Код
возвращает
2015-02-23 12:10:02 +0300
А дата все равно сейчашняя..
Так тоже не катит
2015-02-23 12:10:02
Скажите а можно как то из источника получить url название статьи и присвоить ее создаваемой ноде?
Что бы url остался тот же?
не понимаю вопроса
Не знаю как тут расписать все, вот на дурпал ссылка
http://www.drupal.ru/node/115937
Я там описал проблему, она конечно индивидуальна, но может что-то подскажешь.
Спасибо.
Это вообще возможно?
В момент парсинга брать url .html к примеру страницы с которой парситься и вставлять в алиас создаваемой ноды?
отметьте опцию "Сохранять адреса"
Александр,
1) Есть ли возможность останавливать процесс через php parser_run_in_background($jid); или проверять его статус что например осталось 10 из 30 допарсить?
2) а функция parser_run_in_background($jid); продолжает парсинг или начинает его заного? и как продолжить (функция php) если уже запускался парсер?
3) можно ли выполнить свой код после заверения работы парсера parser_run_in_background($jid); ?
Спасибо за полезный модуль!
1) нет
2) начинает заново. parser_run_batch($jid, FALSE, TRUE);
3) нет
У меня истерика....
Всего??
Я настолько не внимателен что неделю мучаюсь?
facepalm...
XandedX еще раз огромное человеческое СПАСИБО..
Еще 1 маленький вопросик.
У меня уже есть 5000 перенесенных новостей парсером, и я в перенесенных уже в 100-200 что-то правил.
Как мне получить их заново, заставив парсер обновить только этот самый адрес а не трогать в нодах все что он перенес до этого?
с помощью этого модуля никак. обойдите ноды вручную, измените адреса
Спасибо огромное вам за ваши труды, а самое главное за то что вы не просто написали клевый модуль, а еще и отвечаете людям это достойно уважения по моему!
Отписал тут
http://www.drupal.ru/node/115937#comment-636358
Еще раз ОГРОМНОЕ спасибо, я перенес более 20 000 новостей, с 4 сайтов в совокупности, не потерям при этом ничего, в том числе и URL!
Добрый день
Планируете ли добавление поддержки metatag ?
пока нет
Даже не смотрели что там ?
Может есть какие-то мысли ?
Можно было бы совместно ускорить доработку.
Давно парсером не пользовался, но помнится, там есть предобработка - в самом низу добавляемого шаблона - думаю там можно добавить соответствующие данные для полей!?
Подскажите пожалуйста, а как сохранять количество просмотров используя статистику из ядра ?
Столкнулся с небольшой проблемой, может быть её решение может стать доп. фичей такого классного модуля.
Проблема:
Парсим данные "списком". При парсинге страниц через n запросов на странице выводится капча (в соседней вкладке браузера её вбиваешь и продолжается разбор). Так вот, парсер собрал большую базу основных страниц и создал сущности только с тех, где не было капчи. Как теперь экономно пройтись по неудачным страницам?
Вариант решения:
1. обратиться к данным задания и узнать какие адреса обработаны в "Original URL"
2. проверять url страницы (как в белом списке) с помощью php, чтобы его не было в обработанных. Эта проверка отличается от "Код проверки для дальнейшего парсинга страницы" тем, что страница не загружается, а проверяется только её адрес.
То есть, сейчас пришлось для повторного прохода взять адреса
и добавить их в черный список, чтобы по ним повторно не идти и не вызывать капчу
Можно было бы подключить антигате API и распознать капчу. Но мудуль вообще то для официального парсинга, а не для граббинга ;-)
"Код предварительной инициализации" - вот здесь бы иметь возможность: skip_url, parser_stop
Имеется несколько урлов в "Стартовый URL". Как у спарсенной сущности узнать, по какому из этих урлов ее нашли?
_parser_get_url_by_entity_id($entity_type, $entity_id, $jid = NULL)
Это немного не то. Это адрес самой сущности на стороннем сайте. Мне нужен адрес страницы, с которой модуль перешел на эту страницу )
Например, в стартовом урле страница http://xandeadx.ru, задание парсить все ноды, модуль найдет все страницы и спарсит их и _parser_get_url_by_entity_id вернет адрес http://xandeadx.ru/blog/drupal/554, а мне нужен получить адрес http://xandeadx.ru.
такой информации модуль не хранит
Подскажите как обрабатывать файлы без разрешения вида http://bimobject.com/en/content/showproductimage?id=078f4126-2f43-4188-…
проверка return array( 'file' => $doc->find('img')->attr('src') ); дает урл но картинка не загружается
http://xandeadx.ru/blog/drupal/554#comment-10508
Спасибо, работает
А можно запретить создание ноды если title или body пусты?
возвращайте FALSE в "Код проверки для дальнейшего парсинга страницы"
НЕ могу сообразить что вписать в поле:
PHP код для поля Родительские термины
В примечании хоть и есть подсказка, но час уже бьюсь не знаю что вписать.
PHP код, который должен вернуть значение поля (тип: list<taxonomy_term>).
массив идентификаторов родительских терминов
Да это понятно. Но можно образец?
И еще решил проверить парсит ли у меня вообще в таксономию, очистил все поля, оставил только заголовок. Все проверки проходит нормально, но новые сущности не создаются.
Спасибо за ответ. Я думал как-то сложнее указывается )
Почему-то не срабатывает этот код.
Если убираю из него
->attr('id')
, то все работает.Или если писать
$doc->find("table table td[width='100%'] a")->attr('id')
вне цикла, то тоже работает.Весь мозг сломал, не понимаю в чем дело. Все же правильно записано.
метод attr возвращает строку, а не объект phpQuery
Спасибо большое.
Переправил строку так:
($doc->find("table table td[width='100%'] a[id]")
Еще вопрос:
Можно ли указать в какую папку сохранять изображения?
укажите путь в настройках поля
Там можно задать только фиксированный путь. Токены связанные с текущей нодой не работают. Вместо урла или заголовка, возвращается "Batch".
Проблема в том что на сайте доноре все картинки имеют одно название, но находятся каждая в своей папке.
https://www.drupal.org/project/filefield_paths
Большое спасибо.
Изучу.
Здрасте. Очень нужна помощь. Все хорошо парсица, но мне надо связать Карточку товара с товаром в DC. Я так понял там в поле prod_reference должно быть значение SKU товара. У меня на одну карточку товара, может быть несколько товаров. Я использую этот код:
$prods = array();
//вытаскиваю то что нужно
foreach ($doc->find('div.kod-tov p') as $a) {
//Изюавляюсь от букв, оставляю лишь числа в SKU функцией eregi_replace
$int = pq($a)->text();
$prods[] = eregi_replace("([^0-9])", "", $int);
}
return $prods;
Ошибок нет, я не совсем понял описание поля, внизу: "PHP код, который должен вернуть массив значений поля (array(значение1, значение2, ...)) (тип: list)" .
Подскажите, как исправить, пожалуйсто.
возвращать нужно идентификаторы товаров, а не артикли
При парсинге сайта не требующего авторизации выдаёт ошибку:
Попробовал в браузере - всё нормально, в текстовом браузере lynx такая же ошибка 500, но потом после подтверждения приёма
cookie: PHPSESSID=1f2bo2un63mplb03omd8hv70l0 Принять? (Y/N/A)Всегда/V)Никогда)
открывает страницу.Вижу выше написано про cookie:
В первый код добавляем:
В Код предварительной инициализации? Сделал.
В HTTP заголовки:
Но всё равно - 500. Что не так?
Добавлю.
Вот, что выдал код
смотрите какие заголовки отправляет php, я к сожалению не телепат
Как это посмотреть?
поставьте любой снифер
В настройке «Задержка между http запросами» — установлено 15 секунд.
Но за минуту создалось около 30 нод.
Какая причина может быть этому?
Скрин результата парсера
кэш
Создаются дубли нод. И записывается в БД одинаковый remote_id
Я даже не знаю в какую сторону смотреть, с чем может быть связано. У Вас есть предположение?
P.S.
Понял.
Отключил проверку по ID — парсер прошел без дублей.
На каждую новую ноду в логах появляется предупреждение:
Предупреждение (Warning) — из-за моего поля изображений.
Дубли пока создаются — ищу выход.
Дубли создаются при включенном фоновом запуске.
Крон - каждые 9 минут
Парсер - каждые 600 сек.
Как считаете нормальные настройки?
Еще вопрос:
Как остановить парсер запущенный в фоне, без удаления задания?
Добрый день. справится ли этот модуль с парсингом товаров на яндекс.маркет?
Мой заказчик оказался человеком креативным и из 1с грузятся только артикулы а характеристики нужно парсить с яндексмаркета и цеплять к нодам.
XadndeadX , Поможет ли мне Ваш модуль в моем вопросе?
навряд ли
Добрый день.
Парсил товары и после ноды товаров.
Все 900 товаров залились, ноды связаны - всё хорошо.
Но после перехожу в список заданий и вижу, что с заданием по загрузке товаров связано всего 500 товаров (
SELECT COUNT(*) FROM `parser_map` WHERE `jid`=7
=> 500). Запускаю задание заново и появляются ошибки:При этом:
SELECT COUNT(*) FROM `commerce_product` WHERE 1
=> 900 (товаров)SELECT COUNT(*) FROM `parser_map` WHERE `jid`=3
=> 900 (нод)Что-то ломается в таблице parser_map?
Пробовал очищать таблицу commerce_product, и начинать всё заново - после задания по парсингу нод товаров слетает таблица parser_map для задания по товарам.
Пробовал пару раз так.
Что это может быть?
В документе есть изображения, и путь к каждому изображению разный. Что-то типа такого:
Как заменить путь на свой для всех изображений?
Второй день голову ломаю:
Вот так например не работает:
$value = str_replase(($doc->find('img[src]')->html()), 'mypath', $value);
Здравствуйте. Как можно парсить зависимые фильтры на странице. например как на skinon.ru
У сайта-донора часть ссылок включают в себя запятые. Из-за этого парсер выдает ошибки, не может их увидеть.
Можно ли как-то это обойти?
Как установить язык, значение типа token?
где установить?
В поле Язык, задания на парсинг.
Например установить "Русский" для всех импортируемых сущностей.
return 'ru';
Получится? Ведь это не token.
Почему-то нода становится с ru, а поля все с und языком.
Как сделать и поля с ru?
Сайт донор имеет url'ы такого вида: /svetilniki-pod-lampu-nakalivanija-bytovye-(npo,-nbb,-nvo).html т.е. содержит запятые. Из-за них парсер не может скачать эти страницы.
Что можно с этим сделать?
Посмотрел внимательнее - url'ы с запятыми все-таки читаются. Но непонятно почему некоторые страницы не скачиваются. В журнале такая запись:
Всё, разобрался в чем проблема была. Часть ссылок была с .html на конце, хотя на самом деле страницы на которые ведут ссылки без .html.
Решил проблему подправив файл parser.inc. В 1694 строке добавил:
Перед:
В поле body я заменяю путь ссылок на свой:
Но этот код меняет объект, и т.к. поле body стоит выше поля Image, то и изображения пытаются скачаться по новому пути. Из-за этого ошибка.
Как поставить поле Image перед Body, чтобы парсер сначала создавал массив ссылок, а затем обрабатывал Body?
Иногда после очистки кеша, у меня в парсере менялся порядок полей, не знаю с чем это связано. Image оказывался перед Body, и изображения скачивались без проблем. Специально повторить это у меня не получается.
http://xandeadx.ru/blog/drupal/554#comment-11861
Спасибо за ответ. Но все равно не понимаю что клонировать, где можно где нельзя заменять пути.
Ваш модуль парсинга неоценим. Очень хорошая работа. У меня маленький вопросс: Не настраевается поле с ценой. Я использую код:
return array(
'amount' => 1233,
'currency_code' => 'USD'
'data' => array(),
);
Как это настроить? Спасибо.
что вы хотите настроить?
Я хочу настроить поле цены (price) в сущьносте товара на Commerce.
скопируйте ваш код, вставьте в поле
Вот весь код поля:
$price = $doc->find('#id_prod_price')->text();
$price = preg_replace("/[^0-9]/", '', $price);
return array(
'amount' => $price,
'currency_code' => 'USD'
'data' => array(),
)
в массиве запятой не хватает
Не помогло c запятой. А у вас нет примера заполнения поля прайс? любого. В комментарии к полю написано:
array(
'amount' => $amount, // Количество (decimal, optional)
'currency_code' => $currency_code, // Валюта (text, optional)
'data' => $data, // Данные (struct, optional)
)
Я не знаю что можно записать в 'data'?
Разобрался с полем цена (price) для сущьности товара в Commerce:
Должно быть:
return array('amount' => $price, 'currency_code' => 'UAH', 'data'=>array(),);
Добрый день, пользуюсь вашим модулем довольно давно. Модуль супер. Начал недавно делать новый сайт на связке Дру7 + ubercart 3. Встала необходимость парсинга товаров с другого сайта. Парсятся хорошо все поля кроме Артикула и цены, они просто не забиваются в карточку товара. Подскажите как мне их туда запихать??? Я так понимаю им нужно задать тип значения, т.к. в парсинге ясно сказано "PHP код, который должен вернуть значение поля (тип: decimal)." Подскажите пожалуйста как вернуть значение с этим типом.... Сам код у меня такой:
$price = array();
foreach ($doc->find('.styled_table tbody tr td') as price) {
$price[] = pq($price)->text();
}
return $price[4];
http://php.net/manual/ru/function.floatval.php
Ладно... По какой причине не добавляются изображеня? тоже самый Юберкарт. код такой:
array(
'file' => $doc->find('#product_info_image img')->attr('src'),
);
Результат выполнения такой:
Array
(
[file] => /images/products/common/3208.jpg
)
Все работает как бы) но при начале работы парсинга, сразе же выдает ошибку:
Возникла AJAX HTTP ошибка. Полученный код HTTP: 500 Следует отладочная информация. Путь: /batch?render=overlay&id=393&op=do Текст Состояния: Service unavailable (with message) Текст Ответа: EntityMetadataWrapperException: There can be only numerical keyed items in a list. в функции EntityListWrapper->get() (строка 989 в файле /sites/all/modules/entity/includes/entity.wrapper.inc)
Как с этим быть, код для парса изображений использую везде. А тут не выходит в чем причина?
Попробуйте:
Return Array
(
[file] => /images/products/common/3208.jpg,
)
Прошу прощения я так и пробовал
Return Array
(
[file] => /images/products/common/3208.jpg,
);
Парсинг ошибку пишет.... хотя на другом сайте такой код работает. Может ли быть так что версия jquery не та?
> There can be only numerical keyed items in a list.
Это значит, что у вас поле из нескольких значений, а ваш код для одного.
Добавить комментарий