gifts2017

Грабим Яндекс с помощью 1С

Опубликовал Леонид Тумашов (leonidt84) в раздел Программирование - Практика программирования

Статья для участия в конкурсе: "Нападение на Перл-Хабр".
Да, мои дорогие, хабровчане, вы не любите 1С-ников, мы "много зарабатываем и мало знаем". На самом деле это не совсем так (попытайтесь на досуге стать профессионалами одновременно в программировании, бухгалтерии, юриспруденции и ещё куче разных смежных областей). Но сейчас не об этом. В этой статье я опишу весьма необычный метод использования платформы разработки 1С:Предприятие.

Небольшая предистория, которую можно пропустить.

Я программист 1С, да, можете пинать меня ногами. Но так уж пошло, что в молодости я был парнем не богатым, без компьютера, но был безумно влюблен в науку "программирование". Попытки найти хоть какую-нибудь работу связанную с программированием в маленьком провинциальном городе 17-тилетнего юношу без образования и опыта привели в 1С:Франчайзи. И пошло-поехало, мальчик на подхвате, программист 1С, начальник отдела внедрения программного обеспечения на платформе 1С (отдел из двух человек, провинция-с). Сейчас у меня жена, двое детей, кот и своя фирма-франчайзи со мной в роли руководителя, внедренца, программиста, водителя и всего остального. И да, что бы сразу набить авторитет, в ваших глазах, у меня есть борода :)

Чего хочется

Задумал я тут вот собрать себе HTPC. Сказано-сделано. В качестве ОС естественно Windows (я 1С-ник, не забыли?). В качестве медиа центра WMC. Да вот беда, всё работает и показывает, да вот хочется тв-программу прямо сразу в телевизоре, что бы с тайм-шифтом, отсроченной записью, сериалами и прочими плюшками. Порывшись по интернету, обнаружил несколько решений на эту тему, но все они мне показались в чем-то неудобными. То сериалы не распознаются, то программа конвертации пропиетарная, а в самом WMC весьма ограниченный набор телеканалов для загрузки тв-программы. Решил делать свой велосипед. В качестве источника телепрограммы решил выбрать замечательный сервис Яндекс.Телепрограмма. В качестве инструмента добывания программы... угадайте что? Правильно, то единственное на чём я в совершенстве умею программировать - 1С. (А ещё я отлично когда-то программировал в среде Turbo Basic, вот такая профессиональная деградация, смешно да?). Кстати, выбор платформы 1С:Предприятие под эту задачу - оказался крайне удачным. Платформа просто создана для хранения зависимых сложных справочных данных.

Грабим

WMC кушает файлы телепрограмм в собственном формате MXF. Который достаточно хорошо описан в MSDN. Вытягивать будем, как уже говорилось с Яндекса. Проблема в том, что Яндекс не спешит делиться форматом своей телепрограммы (может не нашел), поэтому Ctrl+Shift+I в Chrome, и вперед щелкать по программам. Самое интересное оказалось в последней строчке сетевого запроса, который наш браузер отправил на сервер.

Именно этим запросом мы получаем тв-программу в формате JSON. Изучение формата тоже проблем не создало, все достаточно интуитивно понятно. Итак, создаем в 1С справочник "Провайдеры тв-программы". (Первая строка использовалась мною раньше, когда Яндекс не давал программу в JSON, программу я снимал прямо парсом HTML-страниц. Сейчас я так уже не делаю)

И поехали, пишем затяжку. Простите мой говнокод, писал "по-быстренькому" и для себя.

	Пока  НачальныйДень > 0 ИЛИ ВыборкаДетальныеЗаписи.Следующий() Цикл
		Сообщить("Загружаю программу по каналу: " + ВыборкаДетальныеЗаписи.Канал);
		Для Индикатор2 = НачальныйДень По ЧислоДней Цикл
			ДатаЗагрузки	= НачПериода + Индикатор2 * 86400;
			Сообщить("	Загружаю программу за: " + Формат(ДатаЗагрузки, "ДЛФ=DD"));
			СтрокаВызова	= Провайдер.СтрокаВызова;
			ИДКанала		= ВыборкаДетальныеЗаписи.ИдентификационнаяИнформация;
			СтрокаВызова	= СтрЗаменить(СтрокаВызова, "[ИдентификационнаяИнформацияКанала]", ИДКанала);
			СтрокаВызова	= СтрЗаменить(СтрокаВызова, "[ДатаГГГГ-ММ-ДД]", Формат(ДатаЗагрузки, "ДФ=yyyy-MM-dd"));
			СтрокаВызова	= СтрЗаменить(СтрокаВызова, "[ПродолжительностьВСекундах]", Формат(86400, "ЧГ=0"));
			
			
			СтрокаСтраницы		= РаботаСИнтернет.ПолучитьСтрокуСтраницы(СтрокаВызова);
			
			//начинаем парсинг
			ПарсСтраницы(СтрокаСтраницы, ВыборкаДетальныеЗаписи.Канал, ВыборкаДетальныеЗаписи.РезатьПоТочке);
		КонецЦикла;
		НачальныйДень = 0;
		
		Индикатор1	= Индикатор1 + 1;
	КонецЦикла;

Интересно, будет в комментариях шутка про бейсик переведенный Промптом?

Читаем то, что возвращается с сервера через COM-объект Microsoft.XMLHTTP:

Функция ПолучитьСтрокуСтраницы(УРЛ, Кодировка = "utf-8") Экспорт
	Соединение = ПолучитьCOMОбъект("","Microsoft.XMLHTTP");
	Соединение.open("GET", УРЛ,0,,); //0 - синхронный (по другому 1с не умеет), 1 - асинхронный
	Соединение.send();
	Пока Соединение.readyState <> 4 Цикл
		ОбработкаПрерыванияПользователя();
	КонецЦикла;
	Если Соединение.responseBody = Неопределено Тогда
		Возврат "";
	КонецЕсли;
	
	Текст	= ПреобразоватьСтрокуВУТФ8(Соединение.responseBody, Кодировка);
	Возврат Текст;
КонецФункции

Отлично, создаем справочники Каналы, Передачи и Эпизоды (для сериалов). В 1С на это уходит буквально секунды.

Но просто названия передач так скучны. Добавим ещё описания, картинки, актеров и прочее-прочее, что благосклонно дает нам добрый дедушка Яндекс.

Всё это есть в JSON. Под все создаем соответствующие справочники. А вот саму телепередачу и актеров для телепередач мне показалось удобнее хранить в регистре сведений. В 1С регистр сведений - это такая штука которая в частности используется для хранения структур данных с поддержкой уникальности по неограниченному количеству полей. Обычно регистр сведений используется для хранения настроек учетной политики организации, цен на товары и прочую бухгалтерско-менеджерскую лабудень. В нашем случае он отлично подошел под хранение актеров привязанных к телепрограммам и, собственно, самого расписания телепрограммы.

Ну вот, у нас все затянуто в базу данных и надежно в ней хранится. Это хранение поддерживает сама платформа. Ну и естественно, пишем сам "компилятор" выходного файла.

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

Ну и всё, на стороне HTPC пишем простенький bat-ничек:

C:\Windows\ehome\loadmxf.exe -i tvxb_after.mxf
%SystemRoot%\ehome\ehPrivJob.exe /DoReindexSearchRoot

Profit

Вместо заключения

На всё про-все ушло 2 бессонных ночи. И потом уже в течении годов алгоритм постепенно "допиливался" и прирастал разными полезностями. Это и загрузка рейтинга фильмов с Кинопоиска, и интеллектуальная самообучающаяся (да-да!) система распознавания сериалов (с ними было тяжелее всего).

Так же надеюсь Яндекс не обидится на меня за столь невинную шалость с моей стороны по граббингу телепрограммы. Конфигурацию использую только лично для себя, распространять - не распространял и не собираюсь. Нагрузку на ваш сервер создаю совсем мизерную и всего раз в неделю, так что простите меня, я хороший :)

Я старался сделать статью более популярную, нежели техническую, побольше картинок, поменьше кода, не ругайте меня за это :) Хотелось показать, что 1С:Предприятие это современная СУБД и среда разработки, с помощью которой можно делать не только скучные бухгалтерские программы, но и другие интересные вещи, не имеющие к этой канцелярщине никакого отношения.

См. также

Автор запретил комментарии