Jakiś czas temu pracowałem dla zagranicznego sklepu internetowego, którego jednym z benefitów była dożywotnia zniżka 20% na wybrane produkty. Pomyślałem sobie, dlaczego nie sprzedawać tych produktów na lokalnym rynku z odpowiednią marżą? Niestety mój budżet na biznes był bliski zero. Zakupienie produktów na zapas i oczekiwanie na to, aż ktoś to ode mnie odkupi, nie wchodziło w grę. Postanowiłem wystawić produkty na sprzedaż pomimo tego, że ich fizycznie nie posiadałem.


Jest to HIPOTETYCZNA SYTUACJA - nie stosuję takich praktyk. We wpisie pomijam sprawy prawne i etyczne, ponieważ moim celem jest jedynie zaprezentowanie możliwości arkuszy Google jako prostego narzędzia do web scrapingu oraz automatyzacji pracy.


Opisane tutaj narzędzie do śledzenia produktów znajduje się na moim Google Drive. Przykładowy kod do tego wpisu dostępny jest na moim GitHubie.


Model biznesowy jest prosty. Ktoś kupuje ode mnie produkt, a dopiero wtedy ja zamawiam to ze sklepu internetowego. W zależności od tego, jaką drogę dystrybucji przyjąłem, mogą pojawić się różne problemy. Jednym z nich będzie sytuacja, w której klient zamówi ode mnie wybrany towar, który niedawno stał się niedostępny w sklepie internetowym. Jeżeli będzie to transakcja przez serwis ogłoszeniowy typu OLX, to skończy się to jedynie na niezadowolonym kliencie. W przypadku takich serwisów jak Allegro może być bardziej nieprzyjemnie (na przykład opłata za prowizję). Oczywiście można zabezpieczać się na różne sposoby, np. zaznaczyć w aukcji, że towar jest na zamówienie, ale życie pokazuje, że klienci są różni i mogą nie być wyrozumiali.

Zacząłem od sprawdzenia, czy mój pomysł ma w ogóle sens, tzn. czy jest zapotrzebowanie (i jakie jest zapotrzebowanie) na produkty dostępne na stronie sklepu (za przykład przyjąłem sklep www.military1st.co.uk). Wytypowałem kilkanaście produktów, które wystawiłem w polskich serwisach. Po kilku tygodniach okazało się, że są chętni na produkty w oferowanych cenach. Przede wszystkim okazało się, że na tym zarabiam (zyski z marży są większe niż koszty wystawienia towaru i jego promocji oraz rekompensują poświęcony czas na obsługę biznesu). Mogłem przejść do następnego kroku, czyli zwiększenia oferowanego asortymentu. Przy kilkunastu produktach nie miałem problemu ze sprawdzaniem co najmniej raz dziennie, czy dany produkt jest dostępny na stronie sklepu. Przy większej liczbie produktów takie klikanie mijało się z celem.

Niewiele osób zdaje sobie sprawę z tego, że arkusze Google są świetnym narzędziem do web scrapingu na mniejszą skalę. Co prawda może się to nie sprawdzić przy znanych i popularnych stronach (blokada IP), ale w przypadku zwykłych sklepów sprawdza się doskonale (przy czym sporo zależy od technologii, w jakiej wykonana jest strona internetowa). Na ogół wystarczy dobra znajomość Excela, natomiast największe problemy może sprawić funkcja napisana w JavaScript (“prawie jak w VBA”). Na potrzeby dalszego rozwoju pomysłu stworzyłem arkusz Google do śledzenia produktów, który miał spełniać kilka założeń.

  1. Śledzić wybrane produkty (wklejam jedynie linki)
  2. W przypadku zmiany dostępności produktów wysłać e-mail z alertem

Web scraping z Google Sheets

Na początek wystarczy tabela z kilkoma kolumnami:

  • url
  • title
  • img (pole zbędne, ale chciałem pokazać, że można prezentować w tabeli nawet zdjęcia)
  • in_stock
  • in_stock_prev (poprzedni status do porównania)
  • allegro_id / lub allegro_url / lub inny_serwis_url / itp.

Jedyne kolumny, które uzupełniam ręcznie to link do strony produktu oraz referencje do moich aukcji. Pozostałe pola uzupełniane są automatycznie (albo za pomocą funkcji arkusza albo za pomocą skryptów).

Aby pobrać dane ze strony sklepu (kolumny title, img oraz in_stock) wykorzystałem funkcję IMPORTXML oraz wbudowane w przeglądarkę narzędzia developerskie. Poniżej przykład wykorzystania narzędzi developerskich. Skopiowana ścieżka do wybranego elementu jest zależna od wielu elementów, m.in. od rodzaju jak i wersji przeglądarki.

Ostatecznie ważny jest efekt. W moim przypadku ścieżki XPATH do poszczególnych pól wyglądają następująco:

  • "//h1" dla title
  • "//img[contains(concat(' ',normalize-space(@class),' '),' main-image ')]/@src" dla img
  • "//div[contains(concat(' ',normalize-space(@class),' '),' stock available ')]" dla in_stock

Automatyzacja z Google Sheets

Stworzyłem tabelę przechowującą aktualne dane (aktualizują się one przy każdym odświeżeniu arkusza). Pozostało mi napisanie skryptu, który odświeży dane, porówna kolumny in_stock oraz in_stock oraz wyśle alert w przypadku zmiany wartości. Zaletą arkuszy Google, nad Excelem jest to, że skrypty (makra) można uruchamiać za pomocą czasowych wyzwalaczy. Należy jednak pamiętać aby nie obciążać zbytnio strony, którą śledzimy (w najgorszym wypadku strona zablokuje IP).

Skrypty w Google Sheets są pisane w JavaScript. Edytor Skryptów znajduje się na pasku, w Narzędziach.

Poniżej znajduje się kod funkcji refreshData() wraz z krótkim wyjaśnieniem.

/**
 * Refresh data in military1st.co.uk sheet and send the alert.
 */
function refreshData() {
  var sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("military1st.co.uk");
  var lastRow = sht.getLastRow();
  var rngInStock = sht.getRange(2, 4, lastRow-1, 1);
  
  var data = sht.getRange(2, 1, lastRow-1, 6).getValues()
  var productsInStock = [];
  var productsOutOfStock = [];
  
  var email = 'bartosz.pawel.sekiewicz@gmail.com';
  var subject = 'Product Tracker Alert!';
  var message = '';

  // check changes
  // ...

  // prepare and send alert e-mail
  // ...
  
  // copy from in_stock to in_stock_prev
  // ...
}

Linki do produktów, których status dostępności zmienił się z “niedostępny” na “dostępny” przechowuję w tablicy productsInStock, natomiast tych, których status zmienił się z “dostępny” na “niedostępny” w tablicy productsOutOfStock.

  // check changes
  for (var i in data) {
    var row = data[i];
    
    if ((row[3] != row[4]) && i>0) {
      if (row[3] == true) {
        productsInStock.push(row[0]);
      } else if (row[3] == false) {
        productsOutOfStock.push(row[0]);
      }
    }
  }

Tworzę treść wiadomości e-mail. W przypadku, gdy jest co najmniej jedna zmiana w dostępności produktów wysyłam wiadomość za pomocą funkcji MailApp.sendEmail. UWAGA! Użycie tej funkcji będzie wymagało jednorazowej autoryzacji.

  // prepare and send alert e-mail
  message = message + 'Products in stock:\n\n'
  if (productsInStock.length > 0) {
    message = message + productsInStock.join('\n') + '\n\n'
  } else {
    message = message + 'no change.\n\n'
  }
  
  message = message + 'Products out of stock:\n\n'
  if (productsOutOfStock.length > 0) {
    message = message + productsOutOfStock.join('\n') + '\n\n'
  } else {
    message = message + 'no change.\n\n'
  }
  
  if (productsInStock.length > 0 || productsOutOfStock.length > 0) {
    MailApp.sendEmail(email, subject, message);
  }

Pozostało skopiowanie wartości z kolumny in_stock do kolumny in_stock_prev.

  // copy from in_stock to in_stock_prev
  rngInStock.copyValuesToRange(sht, 5, 5, 2, lastRow);

Na koniec uruchamiam wyzwalacz czasowy - uruchom funkcję refreshData co 6 godzin.

Możliwości dalszego rozwoju

Rozwiązanie oparte o arkusze Google powinno dać sobie radę nawet z kilkoma setkami produktów. Na pewno przy większej liczbie oferowanych produktów przydałoby się zintegrować arkusz z platformą zakupową - chociażby po to, aby automatycznie zawieszać i odwieszać oferty. Być może istnieją dedykowane serwisy do zarządzania sprzedażą, które mogą traktować arkusz Google jako bazę danych naszego “sklepu”.

Warto byłoby także zacząć zbierać dane, aby można je było w przyszłości analizować. Na przykład informacje o dostępności produktów zapisywać dodatkowo do nowej kolumny na osobnym arkuszu. Na podstawie tych danych moglibyśmy opracować algorytm, który zawiesi aukcje zawczasu, jeżeli uzna, że w danym dniu są duże szanse na braki danego produktu w sklepie.

Docelowo trzeba będzie zainwestować w gotowe rozwiązania (lub zlecić komuś stworzenie dedykowanego), które pozwoliłyby zautomatyzować jeszcze więcej elementów (np. wystawianie ofert, mailing) oraz jeszcze bardziej rozszerzyć asortyment. Kiedy wiemy, że biznes działa na małą skalę, łatwiej jest zainwestować pieniądze w bardziej kompleksowe narzędzia.