(import-macros {: map} :lib.macro) (local peg (if (pick-values 1 (pcall require :lpeg)) (require :lpeg) (require :lpeglj))) (local number (require :lib.number)) (local parser (require :parser.parser)) (local fetcher (require :fetcher)) (local utils (require :lib.utils)) (fn format-url [path page] (.. "https://tea108.ru/shop/" path "/?page=" page)) (local product-peg (* ;; a delimiter to clearly separate products (parser.anywhere "data-productid=") ;; url (parser.anywhere (parser.tag :a {:href (peg.Cg (parser.till "\"") :url) :class "product js--hover-preview"})) ;; image (parser.anywhere (* "data-src=\"" (peg.Cg (parser.till "\"") :image) "\"")) ;; name (parser.anywhere (parser.tag :div {:class "product-name"} (peg.Cg (parser.till "") :title))) ;; price (parser.anywhere (parser.tag :span {:class (* "product-price-min" (parser.till "\""))} (peg.Cg (parser.till "") :price))))) (fn normalize [product] (local weight (parser.guess-weight product.title [(* "г" (parser.not "."))])) (local price (number.string->number product.price)) {:site "tea108" :url product.url :title product.title :description product.description :image (.. "https:" product.image) :price price :weight weight :volume (parser.guess-volume product.title) :category product.category :price-per (if (and price weight (< 0 weight)) (/ (math.ceil (* (/ price weight) 10)) 10) nil)}) (fn products [] (fetcher.from-html [{:path "wu-yi-yan-cha" :tags ["Улун" "Фуцзянь"]} {:path "feng-huang-dancong" :tags ["Улун" "Дань Цун"]} {:path "taiwan-oolong" :tags ["Улун" "Тайвань"]} {:path "hong-cha" :tags ["Красный чай"]} {:path "bai-cha" :tags ["Белый чай"]} {:path "sheng" :tags ["Шен пуэр"]} {:path "shu-puer" :tags ["Шу пуэр"]} {:path "tea-ware" :tags ["Посуда"]}] format-url product-peg normalize)) {:products products :title "Tea108" :url "https://tea108.ru"}