К основному контенту

Google и Banggood

Да, в названии сплошная реклама. На певый взгляд, как можно связать поисковик и магазин помимо поиска? На самом же деле речь пойдет не о конкретном поиске Google, а об аналоге MS Excel - Google Sheet. Целью было сделать таблицу со списком нужного мне товара и актуальной ценой на него. Забегая вперед скажу, что проект рабочий на 99%. Остался 1% на получение ценника на товар, в котором возможны опции и от них зависит цена. Для такого варианта есть временное обходное решение.

Итак, план работ следующий:
  1. Создать список товаров
  2. Вбить к ним ссылки
  3. Получить цены с сайта
  4. Посчитать чек 

Подготовка

Для начала проведем анализ данных, которыми обладает товар. Рассмотрим на примере Li-Po аккумулятора. Открываем товар, кликаем правой кнопкой мыши на цене -> проинспектировать элемент.


Там увидим тег, в котором указана стоимость товара
На самом деле у каждого товара есть два тега с ценой: "цена сейчас" (class="now") и "старая цена" (class="old"). Вот тут есть подвох: цена внутри тега указана в валюте, которую вы выставили в своих настройках. Понятно, что выкусывать оттуда ценник не интересно и трудоемко. Если внимательно посмотреть на атрибуты тегов, то можно увидеть, что есть атрибут с именем oriprice (видимо сокращение от original price). По умолчанию, ценник на Banggood.com формируется в USD, а после надстройкой сайта пересчитывается в валюту, которую вы указали в настройках. Этот факт приводит нас к тому, что нужно где-то получить курс USD к вашей валюте. В моем случае это RUB.

Создание списка товаров

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

Вот список товаров у нас есть. Откуда взять цену мы знаем. Осталось получить курс валют, по которому Banggood.com делает пересчет из USD в RUB.

Курс валют с Banggood.com

Простым поиском по коду страницы с ключом currency находим ссылку на JS файл: currency_huilv.js. Именно в нем хранятся курсы и список валют и именно в него мы пойдем за курсом рубля. Но этот момент тоже не так прост. Google Sheet не умеет работать со сторонними JS файлами. Я нашел возможность обратиться к нему через вызов метода fetch класса UrlFetchApp. Это встроенный класс, который позволяет получить содержимое файла по URL адресу.
Где и как взять содержимое курсов валют мы разобрались. Теперь второй вопрос - как обратиться к переменной и получить у нее значение? Тут нам на помощь приходит JS функция eval(). Она позволит сделать из строки кусок JavaScript кода. После этих манипуляций у нас появится доступ к переменной CurrencyCfg, к которой мы сможем обратиться как к массиву.
Наверное на этом этапе уже пора внести ясность и рассказать, куда запихнуть все вышеизложенное. У Google Sheet есть приятный бонус в виде редактора для создания пользовательских функций (макросы в MS Excel). Идем в меню Инструменты -> Редактор скриптов. В редакторе создаем функцию fnBanggoodCurrency с одним параметром sCurrencyName, в котором будет передаваться имя нужной нам вылюты. А сама функция будет возвращать требуемый курс к USD.
Для использования нашей функции достаточно в написать ее в ячейку в виде формулы: =fnBanggoodCurrency(D1)


Цены на товар

Еще одна не простая тема, которая легко решается при помощи формул в Google Sheet. Чуть выше мы нашли, откуда можно взять стоимость товара. Проблема в том, что это цена с сайта и ее получение нужно автоматизировать. Тут нам на помощь придет формула IMPORTXML. Пришлось угробить часик на то, что бы научиться ей пользоваться. Она упорно не хотела идти по абсолютному пути. Возможно из-за скриптов. Но обратиться к элементу и получить нужное значение все же удалось. Давайте разберем формулу:
IMPORTXML(C6; "(//div[@class='now']/@oriprice)[1]"))
Первый аргумент - это наша ссылка на товар. Второй аргумент - XPath. Т.е. мы выбираем все DIV, у которых есть атрибут class и его значение now. Далее берем значение атрибута oriprice. Поскольку условие достаточно абстрактное и под него может попасть даеко не один элемент, мы укажем, что возьмем только первый из них. Это наша текущая цена. По тому же принципу выбирается и старая цена.
Но есть нюанс. На Banggood.com достаточно много товаров с опциями выбора, от которых зависит стоимость. так произошло с товаром Контроллер полета. К сожалению на момент написания статьи решения еще не было. Всвязи с этим было принято решение добавить колонки корректировки, которые заполняются вручную. В результате, если мы не смогли загрузить цену с сайта, она подтянется из колонки коррекции. Не очень красивое, но решение.

Пересчет цены

Еще момент, на который пришлось потратить время. Когда я приступил к пересчету цены из USD в RUB столкнулся с нестыковкой. После пересчета цена в RUB из Google Sheet не совпадала с ценой на Banggood.com в той же валюте. Как оказалось, в том же файле есть несколько индексов, которые корректировали итоговую сумму. В моем случае это был CurrencyBGLoss. После применения этого коэффициента и последующего округления ценники совпали. В итоге получилась счет-фактура с динмическими (ну или почти динамическими) актуальными ценами на товар. В ней можо посчитать итоговую сумму без скидки, со скидкой и сумму самой скидки, что на мой взгляд очень удобно.

Приложения и ссылки

Google Sheet файл

Код пользовательской функции
/**
 * Получает данные о курсе валют с Banggood.com
 **/
function fnBanggoodCurrency(sCurrencyName) {
  // Если валюту не передали, то по умолчанию RUR
  sCurrencyName = (typeof(sCurrencyName) === "undefined")?"RUB":sCurrencyName;
 
  // Считываем файл с курсами валют
  var oResponse = UrlFetchApp.fetch("https://www.banggood.com/cache/static_cache/currency_huilv.js");
 
  // Преобразуем текст в JS код
  eval(oResponse.getContentText());
 
  // Если переменная CurrencyList не определена, то получить список валют не удалось
  if(typeof(CurrencyList) === "undefined"){
    throw "Bangood currency retrieve error";
  }
 
  // Если валюты нет в списке валют, то дпльнейшие действия бесполезны
  if(CurrencyList.indexOf(sCurrencyName) === -1){
    throw "Bangood currency is undefined";
  }
 
  // Получаем курс валюты и умножаем на корректирующий коэффициент
  var nCCourceValue = CurrencyCfg[sCurrencyName][0]*CurrencyBGLoss
 
  // Возвращаем курс требуемой валюты
  return nCCourceValue;
}
Если у вас есть интересные идеи по этой теме и не только - пишите в комментариях.

Комментарии

Популярные сообщения из этого блога

Прямые ссылки на файлы Google диска

В предыдущей статье я рассказал, как подключить свой JavaScript файл к блогу BLOGSPOT . Но для того, что бы их подключить нужны прямые ссылки на файл, а Google диск при предоставлении общего доступа к файлу выдает ссылку на предварительный просмотр, которая никак напрямую не ссылается на файл. Для Google диска прямая ссылка на файл - это ссылка на скачивание. Ниже описаны два способа создания ссылки на скачивание на примере файла prism.js.

События для ведения таблиц

Как и всегда, в пылу проекта внезапно родилась Z табличка. Главный нюанс был в том, что она должна была хранить пароли для авторизации на стороннем сервере. Естественно, никто не хотел хранить пароли в открытом виде, а двустороннее шифрование SAP не умеет без сторонних пакетов и надстроек. Далее, все как обычно - придумали алгоритм, сделали табличку. Дело осталось за малым - нужно шифровать пароли, которые вводит пользователь. Делать отдельную программу нет смысла, поскольку ее функционал мало чем будет отличаться от сгенерированного. Вот здесь на помощь приходят события! С их помощью можно, наверное, все. По крайней мере, я не нашел чего-либо, что нельзя сделать с данными через события.

OOP ALV GRID с HTML шапкой

В этой статье хочу постараться подробно описать и привести пример, как можно создать ALV отчет с таблицей на весь экран и с HTML шапкой вверху. Я не буду описывать начальный этап, где пишется селекционный экран или делается выборка данных. Будем считать, что основа у нас есть и нам нужно просто вывести данные. Главной изюминкой является то, что нужно вывести ALV GRID на экран без использования каких-либо дополнительных элементов на экране. Step-By-Step Шаг 1. Создание окна Создаем самое простое окно с номером 100. На него не нужно кидать никаких контейнеров. Оно нам нужно только для модулей PAI и PBO и вывода на него ALV GRID.