новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Не занимайтесь парсингом HTML - это не надежно!

  • Добавить свою публикацию
  • для этого требуется регистрация

Предисловие

Некоторое время назад мне поступила задача сделать парсер знаменитого ресурса YouTube в виде обработки для 1С:Предприятия 8.2. Обработка должна была иметь возможность ввода строки поиска видео, а также количество найденный видеороликов для обработки. По указанным параметрам производился поиск, а результаты помещались в таблицу с колонками "Имя" (имя видеоролика), "Описание" (описание данного видео) и "Ссылка" (веб-адрес, по которому можно посмотреть видео).

Изображение

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

Какое было решение?

Для того, чтобы заказ был выполнен качественно - принял решение использовать API YouTube вместо парсинга HTML. Во-первых, API меняется очень редко, а если и меняется, то в виде выхода новых версий. При этом старые версии API обычно остаются в рабочем состоянии. Во-вторых, использование API YouTube позволяет выполнять дополнительные доработки в дальнейшем куда быстрее, чем добавлять различного рода условия при парсинге HTML-разметки.

Для решения поставленной задачи из набора инструментов API YouTube нужно было использовать лишь следующее: поиск видео по заданной строке поиска.

На следующем листинге показан программный код для получения списка видеороликов с веб-ресурса  YouTube по указанной строке поиска:

 Процедура ВыполнитьПоискВидео() Экспорт
	
	Если НЕ ЗначениеЗаполнено(СтрокаПоиска) Тогда
		Сообщить("Необходимо ввести строку поиска!");
		Возврат;
	КонецЕсли;
	
	Если НЕ ЗначениеЗаполнено(КоличествоВидео) Тогда
		Сообщить("Не введено количество видео для обработки!");
		Возврат;
	КонецЕсли;
	
	// Очищаем таблицу результатов поиска видеозаписей
	Видеозаписи.Очистить();
	
	// Текущая обрабатываемая часть 
	// (обрабатывать видео на YouTube можно только порциями. Максимальная порция - 50 видео)
	ОбрабатываемаяЧасть = 1;
	// В переменную будет записано общее количество найденных видео
	ВсегоРезультатов = 0;
	// Количество видеозаписей, обработаных и добавленных в таблицу "Видеозаписи"
	ОбработаноРезультатов = 0;
	// Флаг показывает ход процесса обработки видео с YouTuba'а. 
	// ИСТИНА - идет обработка, ЛОЖЬ - обработка завершена
	ОбрабатываетсяРезультат = Истина;
	
	ТекЭл = Неопределено; // Текущая строка табличной части "Видеозаписи"

	// Создаем временный файл для записи ответа сервера "YouTube"
	ИмяВходящегоФайла = ПолучитьИмяВременногоФайла(); 
	
	// ВНИМАНИЕ!!! Для работы с такими сайтами как YouTube и RuTube 
	// правильнее не парсить HTML-код, а использовать API.
	// Поскольку HTML-код постоянно меняется с доработками этих 
	// сервисов и обработка далее будет работать не стабильно.
	// Например, описание API YouTube можно посмотреть по ссылке 
	// https://developers.google.com/youtube/2.0/developers_guide_protocol_api_query_parameters?hl=ru
	// Описание API RUTUBE здесь: http://rutube.ru/info/to_developers/
	
	Пока ОбрабатываетсяРезультат Цикл		
		// Посылаем запрос на получение списка видео по запросу в строке поиска.
		HTTP = Новый HTTPСоединение("gdata.youtube.com"); // Сервер YouTube
		HTTP.Получить("feeds/api/videos?q="+
					  // Строка поиска
					  СтрокаПоиска+"&start-index="
					  // Номер порции для обработки
					  +Формат(ОбрабатываемаяЧасть, "ЧГ=0")+
					  // Количество видео в порции
					  "&max-results=50", ИмяВходящегоФайла); 		
		                                                        
		// Читаем полученный XML-файл 
		Чтение = Новый ЧтениеXML;
		Чтение.ОткрытьФайл(ИмяВходящегоФайла);
		
		// Флаг позволяет определить обрабатывается ли в даннымй момент
		// элемент видео или другие данные
		ОбнаруженЭлемент = Ложь; 
		
		Пока Чтение.Прочитать() Цикл // Обходим весь XML-файл ответа
			// Для прочих данных
			Если НЕ ОбнаруженЭлемент Тогда
				// Получаем всего количество найденных видео
				Если Чтение.Имя = "openSearch:totalResults" И 
						НЕ ЗначениеЗаполнено(ВсегоРезультатов) Тогда
					Чтение.Прочитать();
					ВсегоРезультатов = ПреобразоватьКЧислу(Чтение.Значение);
					Продолжить;
				КонецЕсли;
				// Если в имени ключа содержится "entry", то это означает 
				// начало описания видеозаписи (обраружен элемент)
				Если Найти(Чтение.Имя, "entry") > 0 Тогда
					ОбнаруженЭлемент = Истина;	
					
					// Добавляем строку в таб. часть "Видеозаписи", 
					// далее будем ее заполнять
					ТекЭл = Видеозаписи.Добавить(); 
					Продолжить;
				КонецЕсли;
			// Для элемента (видеозаписи)
			ИначеЕсли ОбнаруженЭлемент Тогда
				// В поле "title" содержится название видео
				Если Чтение.Имя = "title" Тогда
					Чтение.Прочитать();
					ТекЭл.Имя = Чтение.Значение; 
					Если ЗначениеЗаполнено(Чтение.Значение) Тогда
						Чтение.Прочитать();
					КонецЕсли;
					Продолжить;
				КонецЕсли;
				// В поле "content" содержится описание видео
				Если Чтение.Имя = "content" Тогда
					Чтение.Прочитать();
					ТекЭл.Описание = Чтение.Значение; 
					Если ЗначениеЗаполнено(Чтение.Значение) Тогда
						Чтение.Прочитать();
					КонецЕсли;
					Продолжить;
				КонецЕсли;
				// В поле "link" содержится ссылка на видео
				Если Чтение.Имя = "link" И НЕ ЗначениеЗаполнено(ТекЭл.Ссылка) Тогда
					ТекЭл.Ссылка = Чтение.ПолучитьАтрибут("href"); 
					Продолжить;
				КонецЕсли;
				// Если был найден элемент XML, в имени которого содержится 
				// "entry" - значит описание видеозаписи закончено.
				// Можно перейти к обработке следующего видео
				Если Найти(Чтение.Имя, "entry") > 0 Тогда
					ОбнаруженЭлемент = Ложь; // Обработка видеозаписи завершена 
					ОбработаноРезультатов = ОбработаноРезультатов + 1;
					// Если обработано результатов соответствует 
					// максимуму найденного или установленному количеству обраб. видео 
					// то нужно прекратить обработку результатов поиска видео
					Если ОбработаноРезультатов = ВсегоРезультатов 
							ИЛИ ОбработаноРезультатов = КоличествоВидео Тогда
						ОбрабатываетсяРезультат = Ложь;
						Прервать;
					КонецЕсли;
					Продолжить;
				КонецЕсли;  
			КонецЕсли;  			
		КонецЦикла;
		Чтение.Закрыть();
		
		// Если обработано результатов соответствует максимуму 
		// найденного или установленному количеству обраб. видео 
		// то нужно прекратить обработку результатов поиска видео
		Если ОбработаноРезультатов = ВсегоРезультатов
				 ИЛИ ОбработаноРезультатов = КоличествоВидео Тогда
			ОбрабатываетсяРезультат = Ложь;
		КонецЕсли;
		
	КонецЦикла;
		
Конецпроцедуры

// Функция преобразования строки к числу
Функция ПреобразоватьКЧислу(ЧислоСтрока)	
	Попытка
		Возврат Число(ЧислоСтрока);
	Исключение
		Возврат 0;
	КонецПопытки;	
КонецФункции

 Задача выполнена!

Итог

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

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

 
0
Читайте также
Выполнение запроса в общем модуле
"Вынести выполнение запроса в функцию общего модуля"
Установка PostgreSQL 9.0.3-3.1C на Windows Server 2008 x64
"Windows Server 2008 x64 Как установить PostgreSQL 9.0.3-3.1C"
Особенность использования механизма характеристик в СКД
Отчет на СКД -механизм зхарактеристик
Разработки
Каталог с изображениями в Торговле
Как создать каталог с картинками в УТ 10.3
Моя "Доминикана" или Я и Рафаэль.
Как рисовать с html в 1С
Универсальный почтовый калькулятор
Расчет почтовых тарифов
Универсальный почтовый калькулятор
Расчет почтовых тарифов
Еще от автора
≡ к списку статей