gifts2017

Поиск товаров по штрихкоду на сайте www.ean13.info

Опубликовал Данила Володькин (skif47) в раздел Обработки - Обработка справочников

Описание товаров, имеющих штрихкод, с некоторой вероятностью можно найти на www.ean13.info. Обработка выполняет этот поиск. Немного доработав, можно использовать для наполнения справочника "Номенклатура" с помощью сканера штрихкодов.

Принцип действия очень простой.

http://www.ean13.info/4604290001691.htm - пример описания товара по его штрихкоду. Т.е. в форме обработки задаем список желаемых штрихкодов, на каждый из них запрашивается соответствующая страница.

Далее страница парсится по этому алгоритму: http://infostart.ru/public/308253/.

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

Для использования обработки не требуется регистрация. Однако при активном употреблении через какое-то время сайт начинает выдавать капчу вместо привычного описания товаров. В каталоге также имеется платный API (5000 запросов за 10 USD). 

UPD:

Если же ключ API у вас есть, то достаточно передать его вторым параметром в метод "ЗаполнитьТаблицуТоваров" (или указать в форме, если вы скачали обработку полностью), после чего получение данных о товарах пойдет живее и без неизбежного бана. При "боевом" использовании (более 50-100 запросов) это рекомендованный вариант работы.

Тестовый ключ xccvg55kh43jjf указан здесь http://www.mpk.dn.ua/ean13_info_platnoje_api.html и дает доступ только к одному товару: 4603172600007, Сигареты "Прима люкс" без фильтра.

P.S. Выкладываю исходники модуля объекта (в формах кода почти нет). В комментариях ниже есть альтернативный метод парсинга.

 

Перем СоединениеССервером;//кэш

Функция getXPathElement(sXPath, objElement )
	//взял здесь: http://infostart.ru/public/308253/
	
     // Split the xpath statement
    лМассивХР = СтрЗаменить(sXPath, "/",Символы.ПС);
    лИндексНоды = СтрПолучитьСтроку(лМассивХР,1); //лИндексНоды
    Если Найти(лИндексНоды, "@id") > 0 Тогда
        лИмя = СтрЗаменить(лИндексНоды,"[","");
        лИмя = СтрЗаменить(лИмя,"]","");
        лИмя = СтрЗаменить(лИмя,"=",Символы.ПС);
        лИмя = СтрПолучитьСтроку(лИмя,2);
        лИмя = СтрЗаменить(лИмя,"""","");
        ЛobjElement = objElement.ПолучитьЭлементПоИдентификатору(лИмя); 
        лМассивХР = СокрЛП(СтрЗаменить(лМассивХР,СтрПолучитьСтроку(лМассивХР,1),""));
        лИндексНоды = СтрПолучитьСтроку(лМассивХР,1);
    Иначе 
        ЛobjElement = objElement;
    КонецЕсли;    
    
    If Not Найти(лИндексНоды, "[") > 0 Then
        sNodeName = лИндексНоды;
        lNodeIndex = 1;
    Else
        лИндексНоды = СтрЗаменить(лИндексНоды, "[",Символы.ПС);
        лИндексНоды = СтрЗаменить(лИндексНоды, "]",Символы.ПС);
        sNodeName =  СтрПолучитьСтроку(лИндексНоды,1);
        lNodeIndex = Число(СтрПолучитьСтроку(лИндексНоды,2));
    EndIf;
    sRestOfXPath ="";
    Для Сч =2 По СтрЧислоСтрок(лМассивХР) Цикл
        sRestOfXPath = sRestOfXPath + ?(Сч=2,"","/")+СтрПолучитьСтроку(лМассивХР,Сч);        
    КонецЦикла;
     
    getXPathElement = Неопределено;
    
    лСчЭлементов = 0;
    For lCount = 0 To ЛobjElement.ДочерниеУзлы.Количество() - 1 Цикл
        If ВРег(ЛobjElement.ДочерниеУзлы.Item(lCount).ИмяУзла) = ВРег(sNodeName) Then
            лСчЭлементов = лСчЭлементов + 1;
            If lNodeIndex = лСчЭлементов Then
                If sRestOfXPath = "" Then
                    getXPathElement = objElement.ДочерниеУзлы.Элемент(lCount);
                    Прервать;
                Else
                    getXPathElement = getXPathElement(sRestOfXPath, ЛobjElement.ДочерниеУзлы.Элемент(lCount));
                    Прервать;
                EndIf;
            EndIf;
        EndIf;
    КонецЦикла;
    Возврат getXPathElement;
КонецФункции

Функция ПолучитьРезультатПарсингаWWW(ЛокальноеИмяФайла)
	
	РезультатПарсинга = Новый Структура;
	
	ЧтениеHTML = Новый ЧтениеHTML;
	ЧтениеHTML.ОткрытьФайл(ЛокальноеИмяФайла,"UTF8");
	ПостроительДом = Новый ПостроительDOM;
	Документ = ПостроительДом.Прочитать(ЧтениеHTML);
	ЧтениеHTML.Закрыть();
	
	//теперь XPATH, который не совсем XPATH
	ТекстЗапроса = "html[2]/body/div[1]/div/div[3]/div[2]";
	
	СекцияОписания = getXPathElement(ТекстЗапроса,Документ);
	
	Попытка
		РезультатПарсинга.Вставить("Наименование",	getXPathElement("h1/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Успешно",		НЕ (РезультатПарсинга.Наименование = "Товар не найден в базе данных"));
	Исключение	
		//неправильный формат штрихкода или еще какая беда
		РезультатПарсинга.Вставить("Успешно",		Ложь);
	КонецПопытки;	
	
	Если РезультатПарсинга.Успешно Тогда
		РезультатПарсинга.Вставить("ТипШтрихКода",	getXPathElement("ul/li[2]/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Страна",		getXPathElement("ul/li[3]/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Производитель",	getXPathElement("ul/li[4]/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Бренд",			getXPathElement("ul/li[5]/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Категория",		getXPathElement("ul/li[6]/span",СекцияОписания).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Описание",		СокрЛП(getXPathElement("ul/li[7]/span/#text",СекцияОписания).ТекстовоеСодержимое));
	КонецЕсли;	
	
	Возврат РезультатПарсинга;
	
КонецФункции

Функция ПолучитьРезультатПарсингаXML(ЛокальноеИмяФайла)
	
	РезультатПарсинга = Новый Структура;
	
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.ОткрытьФайл(ЛокальноеИмяФайла,,,"UTF8");
	
	ПостроительДом = Новый ПостроительDOM;
	Попытка
		Дерево = ПостроительДом.Прочитать(ЧтениеXML);
	Исключение
		//Вместо XML сервер может вернуть текст "Отсутствует ключ для доступа к API" (видимо, если лимит запросов ключа исчерпан)
		РезультатПарсинга.Вставить("Успешно",Ложь);
		Возврат РезультатПарсинга;
	КонецПопытки;
		
	ЧтениеXML.Закрыть();
	
	Попытка
		РезультатПарсинга.Вставить("Успешно",		getXPathElement("ean13/valid",Дерево).ТекстовоеСодержимое="1");
		РезультатПарсинга.Вставить("Наименование",	getXPathElement("ean13/name",Дерево).ТекстовоеСодержимое);
	Исключение	
		//неправильный формат штрихкода или еще какая беда
		РезультатПарсинга.Вставить("Успешно", Ложь);
	КонецПопытки;	
	
	Если РезультатПарсинга.Успешно Тогда
		//РезультатПарсинга.Вставить("ТипШтрихКода",			getXPathElement("ean13/name",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Страна",					getXPathElement("ean13/contry",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Производитель",				getXPathElement("ean13/man",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Бренд",						getXPathElement("ean13/brand",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Категория",					getXPathElement("ean13/cat",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("Описание",					getXPathElement("ean13/desc",Дерево).ТекстовоеСодержимое);
		РезультатПарсинга.Вставить("ДатаПоследнегоИзменения",	ДатаXMLВ1С(getXPathElement("ean13/lastmod",Дерево).ТекстовоеСодержимое));
		РезультатПарсинга.Вставить("ОсталосьЗапросовAPI",		Число(getXPathElement("ean13/yourlimit",Дерево).ТекстовоеСодержимое));
	КонецЕсли;	
	
	Возврат РезультатПарсинга;
	
КонецФункции

Функция ДатаXMLВ1С(ЗНАЧ ДатаСтрокой)
	
	//Пример: 2014-09-05T19:03:38+04:00
	
	Перем Результат;
	
	ДатаСтрокой = Лев(ДатаСтрокой,19);
	ДатаСтрокой = СтрЗаменить(ДатаСтрокой,"-","");
	ДатаСтрокой = СтрЗаменить(ДатаСтрокой,":","");
	ДатаСтрокой = СтрЗаменить(ДатаСтрокой,"T","");
	
	Попытка
		Результат = Дата(ДатаСтрокой);
	Исключение
		//не критично
	КонецПопытки;
	
	Возврат Результат;
	
КонецФункции

Функция ПроверитьШтрихкод(Штрихкод,КлючAPI)
	
	//можно еще кэширование добавить
	
	Если НЕ ЗначениеЗаполнено(КлючAPI) Тогда
		//ЛокальноеИмяФайла = "c:\pricat\Doc\ean13.info\Капот 2107-8401012, штрих-код_ 4604290001363 - Ean13.info, информация о товаре.html";
		ЛокальноеИмяФайла = ПолучитьФайлHTTP("/"+Штрихкод+".htm");
		Результат = ПолучитьРезультатПарсингаWWW(ЛокальноеИмяФайла);
	Иначе
		ЛокальноеИмяФайла = ПолучитьФайлHTTP("/api.php?code="+Штрихкод+"&key="+КлючAPI); // /api.php?code=4603172600007&key=xccvg55kh43jjf
		Результат = ПолучитьРезультатПарсингаXML(ЛокальноеИмяФайла);
	КонецЕсли;
	
	УдалитьФайлы(ЛокальноеИмяФайла);
	Возврат Результат;
	
КонецФункции

Функция ПолучитьФайлHTTP(АдресЗапроса)
	
	Если СоединениеССервером=Неопределено Тогда
		Сервер = "www.ean13.info";
		СоединениеССервером = Новый HTTPСоединение(Сервер);
	КонецЕсли;	
	ИмяФайлаОтвета = ПолучитьИмяВременногоФайла();
	СоединениеССервером.Получить(АдресЗапроса,ИмяФайлаОтвета);
	Возврат ИмяФайлаОтвета;
	
КонецФункции	

Функция ПолучитьТестовыеДанные() Экспорт
	
	Возврат 
	
	"4603172600007
	|4604290001363
	|
	|4690449004650
	|штрихкод, который должен свалиться
	|4690449004651";
	
КонецФункции	

Процедура ЗаполнитьТаблицуТоваров(СписокШтрихкодов,КлючAPI="") Экспорт
	
	Товары.Очистить();
	
	Для Сч=1 по СтрЧислоСтрок(СписокШтрихкодов) Цикл
		ТекШтрихкод = СтрПолучитьСтроку(СписокШтрихкодов,Сч);
		Если СокрЛП(ТекШтрихкод)<>"" Тогда
			
			НовСтрока = Товары.Добавить();
			НовСтрока.Штрихкод = ТекШтрихкод;
			
			Попытка
				РезультатПарсинга = ПроверитьШтрихкод(СокрЛП(ТекШтрихкод),КлючAPI);
				ЗаполнитьЗначенияСвойств(НовСтрока,РезультатПарсинга);
			Исключение
				_Ошибка = ОписаниеОшибки();
				Сообщить("Не найден штрихкод "+ТекШтрихкод+" по причине:
				|"+_Ошибка);
			КонецПопытки;	
			
		КонецЕсли;	
	КонецЦикла;	
	
КонецПроцедуры	

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Поиск товаров в ean13.info
.epf 17,72Kb
16.01.16
15
.epf 17,72Kb 15 Скачать

См. также

Contragent+ 5.0 от 2 500
Подписаться Добавить вознаграждение

Комментарии

1. Роман Ложкин (webester) 09.01.16 10:49
Прошу прощения, что мешаю зарабатывать мани, но там же несколько строк.
			Соединение = Новый HTTPСоединение("www.ean13.info");
			Ответ = Соединение.Получить(Новый HTTPЗапрос(""+КакойТоШтрихКод+".htm"));
			
			РезультатПоиска = Новый Структура("Статус, Товар,Страна,Производитель,Штрихкод", СтрокаСообщения);

			Если Ответ.КодСостояния = 200 Тогда
				ЧтениеХТМЛ = Новый ЧтениеHTML;
				ЧтениеХТМЛ.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
				ПостроительДОМ = Новый ПостроительDOM;
				
				ДокументХТМЛ = ПостроительДОМ.Прочитать(ЧтениеХТМЛ);
				ЭлементыДОМ = ДокументХТМЛ.ПолучитьЭлементыПоИмени("span");
				Если ЭлементыДОМ[1].ТекстовоеСодержимое = "Товар не найден в базе данных" Тогда
					//может будем как то обрабатывать
				Иначе
					РезультатПоиска.Статус = "Найдено в интернете";
					РезультатПоиска.Товар = ЭлементыДОМ[1].ТекстовоеСодержимое;
					РезультатПоиска.Страна = ЭлементыДОМ[4].ТекстовоеСодержимое;
					РезультатПоиска.Производитель = ЭлементыДОМ[5].ТекстовоеСодержимое;
					РезультатПоиска.Штрихкод = ТекКод;
				КонецЕсли; 
			Иначе
				//может будем как то обрабатывать
			КонецЕсли; 


...Показать Скрыть
2. Данила Володькин (skif47) 09.01.16 12:08
(1) webester, зарабатывание мани не является моей основной целью. Так что нет, не мешаете. Кажется странным, что вместо того, чтобы оформить свой код в публикацию, вы пишете его в комментариях к чужой публикации.
Теперь по существу. Вы часто ищете штрихкоды на этом сайте? С какой целью - проверить существующие в вашей базе товары или добавить новые? Имеет смысл добавить в обработку поддержку API и попробовать пообщаться с хозяевами базы на тему "дайте тарифы попроще и с оплатой не через сбербанк"? Создание номенклатуры по найденному стоит добавлять?
3. Данила Володькин (skif47) 09.01.16 12:11
Эти вопросы ко всем читающим, кстати )
4. Роман Ложкин (webester) 09.01.16 12:23
(2)
Кажется странным, что вместо того, чтобы оформить свой код в публикацию, вы пишете его в комментариях к чужой публикации

Мне показалось излишним делать публикацию на каждые 10 строк кода. Слишком простая штука. Поэтому добавил когда увидел ваш пост, раз вы все таки сочли нужным делать для этого пост. Мне кажется вам надо было сразу выкладывать код, раз вам не нужны мани.Что бы мог воспользоваться любой даже без аккаунта на ИС.

Вы часто ищете штрихкоды на этом сайте?

Нет.

С какой целью - проверить существующие в вашей базе товары или добавить новые?

Запускаю работающую аптеку, неохота руками все набирать. по макс убрать ручной труд, насколько возможно. Будем искать названия в файлах поставщиков, если не найдется, то в базе, если и там не будет, то наберет фармацевт название ручками.

Имеет смысл добавить в обработку поддержку API и попробовать пообщаться с хозяевами базы на тему "дайте тарифы попроще и с оплатой не через сбербанк"?
Вам виднее, но мне кажется добавлять апи которое работает с апи, какой то перебор.

Создание номенклатуры по найденному стоит добавлять?
Слишком щепетильный вопрос, для аптеки критичен производитель, для вас наверно нет, где то должны характеристики заполняться, а к ним уже штрихкод, где то не должны. В разных конфигурациях по разному это должно происходить, если вам хочется этим заниматься, то почему бы и нет? Я честно сказать практический смысл нахожу с трудом. Кому надо тот себе напишет, а кто не может, может заказать за недорого, создание номенклатуры опять же несколько строк кода если под конкретное решение.
5. Данила Володькин (skif47) 10.01.16 00:34
(4) webester, Согласен, исходники выложил.
6. Данила Володькин (skif47) 10.01.16 01:23
(4) webester,
Будем искать названия в файлах поставщиков

Если не секрет, что вообще в этом случае предоставляют поставщики? Прайсы, накладные, CommerceML? В моем представлении, фармацевтика - достаточно прокачанная отрасль в плане IT.

добавлять апи которое работает с апи, какой то перебор.
речь шла о том, чтобы запрашивать инфу о товарах не парсингом страниц, а через предназначенный для этого API. Это может пригодиться при необходимости запросить 50-100 и больше штрихкодов (у меня капча вылезла примерно после 50 запросов). Вам действительно ни к чему, если редко туда ходите.
7. Роман Ложкин (webester) 10.01.16 18:04
(6)
Если не секрет, что вообще в этом случае предоставляют поставщики?

Кто, во что горазд. txt, xls, xml последнее прилетело в html.Какой то бред честное слово.Настолько все строго с этими ценами, условиями и тд такой бардак в поставке накладных.
8. Сергей Соколов (sfs1981) 04.02.16 14:02
Добрый день.
Как представитель ean13.info, добавлю от себя:
1. Тарифы попроще у нас есть, для тех кто берет доступ оптом, существуют скидки. Если нужно меньше чем 5000 запросов - пиште, договоримся.
2. Мы реализовали обратное АПИ. Теперь, при передаче нам данных о товарах, которых у нас нет , вы получаете бесплатные запросы к базе (1 новый товар = 10 бесплатных запросов).
Ну и похвастаемся: размер базы приближается к 10 млн. товаров.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа