apress-yandex_market 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +30 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +3 -0
  5. data/CHANGELOG.md +9 -0
  6. data/Gemfile +3 -0
  7. data/README.md +3 -0
  8. data/Rakefile +7 -0
  9. data/apress-yandexmarket.gemspec +36 -0
  10. data/dip.yml +41 -0
  11. data/docker-compose.development.yml +13 -0
  12. data/docker-compose.drone.yml +7 -0
  13. data/docker-compose.yml +9 -0
  14. data/lib/apress/yandex_market/api/client.rb +79 -0
  15. data/lib/apress/yandex_market/api/error.rb +19 -0
  16. data/lib/apress/yandex_market/api/page_error.rb +9 -0
  17. data/lib/apress/yandex_market/api.rb +9 -0
  18. data/lib/apress/yandex_market/presenters/base.rb +49 -0
  19. data/lib/apress/yandex_market/presenters/model.rb +19 -0
  20. data/lib/apress/yandex_market/presenters.rb +8 -0
  21. data/lib/apress/yandex_market/readers/base.rb +54 -0
  22. data/lib/apress/yandex_market/readers/category.rb +117 -0
  23. data/lib/apress/yandex_market/readers/model_by_category.rb +145 -0
  24. data/lib/apress/yandex_market/readers.rb +8 -0
  25. data/lib/apress/yandex_market/version.rb +5 -0
  26. data/lib/apress/yandex_market.rb +9 -0
  27. data/spec/apress/yandex_market/api/client_spec.rb +46 -0
  28. data/spec/apress/yandex_market/readers/category_spec.rb +46 -0
  29. data/spec/apress/yandex_market/readers/model_by_category_spec.rb +29 -0
  30. data/spec/fixtures/get_category_with_invalid_id.yml +81 -0
  31. data/spec/fixtures/get_root_categories.yml +82 -0
  32. data/spec/fixtures/read_models_from_category.yml +29960 -0
  33. data/spec/fixtures/read_two_categories.yml +3600 -0
  34. data/spec/fixtures/read_two_categories_with_page_error.yml +1983 -0
  35. data/spec/spec_helper.rb +27 -0
  36. metadata +240 -0
@@ -0,0 +1,145 @@
1
+ require 'apress/yandex_market/readers/base'
2
+ require 'apress/yandex_market/readers/category'
3
+ require 'apress/yandex_market/presenters'
4
+
5
+ module Apress
6
+ module YandexMarket
7
+ module Readers
8
+ # Ридер моделей Яндекс.Маркета по категориям
9
+ #
10
+ # Examples
11
+ #
12
+ # reader = Apress::YandexMarket::Readers::ModelByCategory.new(region_id: 225,
13
+ # token: 'qwerty',
14
+ # categories: 'Авто; Дом и дача')
15
+ # # => #<Apress::YandexMarket::Readers::ModelByCategory ...>
16
+ #
17
+ # reader.each_row |model|
18
+ # puts model
19
+ # end
20
+ # # => {
21
+ # :__line__=>1,
22
+ # :__column__=>1,
23
+ # :id=>217189255,
24
+ # :name=>"Caviale Крем для лица Витамин Е",
25
+ # :link=>"https://market.yandex.ru/product/217189255?hid=8476099&pp=929&clid=2326601&distr_type=7",
26
+ # :description=>"время нанесения: дневной/ночной, эффект: увлажнение",
27
+ # :photo=>{:url=>"https://avatars.mds.yandex.net/get-mpic/331398/img_id833813452766046986.jpeg/orig"},
28
+ # :photos=>[
29
+ # {:url=>"https://avatars.mds.yandex.net/get-mpic/331398/img_id833813452766046986.jpeg/orig"},
30
+ # {:url=>"https://avatars.mds.yandex.net/get-mpic/331398/img_id8176844263482482207.jpeg/orig"},
31
+ # {:url=>"https://avatars.mds.yandex.net/get-mpic/933699/img_id2264997491683174997.jpeg/orig"}
32
+ # ],
33
+ # :price=>{:min=>"68"},
34
+ # :vendor=>{:name=>"Caviale"},
35
+ # :specification=>[
36
+ # {
37
+ # :features=>[
38
+ # {:value=>"время нанесения: дневной/ночной"},
39
+ # {:value=>"эффект: увлажнение"}
40
+ # ]
41
+ # }
42
+ # ]
43
+ # }
44
+ # {
45
+ # :__line__=>2,
46
+ # :__column__=>1,
47
+ # :id=>217189256,
48
+ # ...
49
+ # }
50
+ class ModelByCategory < Base
51
+ FIELDS = %w(
52
+ MODEL_CATEGORY
53
+ MODEL_PHOTO
54
+ MODEL_PHOTOS
55
+ MODEL_PRICE
56
+ MODEL_SPECIFICATION
57
+ MODEL_VENDOR
58
+ ).join(',').freeze
59
+
60
+ class << self
61
+ def allowed_options
62
+ Readers::Category.allowed_options
63
+ end
64
+ end
65
+
66
+ attr_reader :category_reader
67
+
68
+ # Public: инициализация ридера
69
+ #
70
+ # options - Hash, параметры ридера
71
+ # :region_id - идентификатор региона (необязательный)
72
+ # :token - токен для доступа к API Яндекс.Маркета
73
+ # :categories - список категорий для загрузки моделей Яндекс.Маркета
74
+ #
75
+ # Returns an instance of Readers::ModelByCategory
76
+ def initialize(options)
77
+ super
78
+ @category_reader = Readers::Category.new(options)
79
+ end
80
+
81
+ # Public: читаем товары из API и фильтруем необходимые поля для использования далее в препроцессоре Кирби
82
+ #
83
+ # Returns nothing
84
+ def each_row
85
+ presenter = Presenters::Model.new
86
+
87
+ category_reader.each_row do |category|
88
+ models = Set.new
89
+
90
+ begin
91
+ process_models(models, category.fetch(:id), 'DESC')
92
+ rescue Api::PageError
93
+ begin
94
+ process_models(models, category.fetch(:id), 'ASC')
95
+ rescue Api::PageError
96
+ end
97
+ end
98
+
99
+ models.each { |model| yield presenter.expose(model) }
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def process_models(processed_models, category_id, sort_direction)
106
+ page = 1
107
+
108
+ loop do
109
+ models = get_models(category_id, page, sort_direction)
110
+
111
+ models.each do |model|
112
+ next if category_id != model.fetch(:category).fetch(:id)
113
+ return if processed_models.include? model
114
+
115
+ processed_models << model
116
+ end
117
+
118
+ break if models.size < PAGE_SIZE
119
+
120
+ page += 1
121
+ end
122
+ end
123
+
124
+ def get_models(category_id, page, sort_direction)
125
+ sleep(SLEEP_TIME)
126
+
127
+ with_rescue_temporary_errors do
128
+ client.
129
+ get(
130
+ "categories/#{category_id}/search",
131
+ geo_id: @region_id,
132
+ result_type: 'MODELS'.freeze,
133
+ sort: 'DATE'.freeze,
134
+ how: sort_direction,
135
+ fields: FIELDS,
136
+ count: PAGE_SIZE,
137
+ page: page
138
+ ).
139
+ fetch(:items)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,8 @@
1
+ module Apress
2
+ module YandexMarket
3
+ module Readers
4
+ autoload :Category, 'apress/yandex_market/readers/category'
5
+ autoload :ModelByCategory, 'apress/yandex_market/readers/model_by_category'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Apress
2
+ module YandexMarket
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'apress/yandex_market/version'
2
+
3
+ module Apress
4
+ module YandexMarket
5
+ autoload :Api, 'apress/yandex_market/api'
6
+ autoload :Presenters, 'apress/yandex_market/presenters'
7
+ autoload :Readers, 'apress/yandex_market/readers'
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Apress::YandexMarket::Api::Client do
4
+ let(:client) { described_class.new 'some_secret_token' }
5
+
6
+ describe '#get' do
7
+ context 'get root categores' do
8
+ subject { client.get('categories', geo_id: 225, count: 30) }
9
+
10
+ it do
11
+ VCR.use_cassette 'get_root_categories' do
12
+ expect(subject).to be_a Hash
13
+ expect(subject).to include(:categories, :context, :status)
14
+ expect(subject[:status]).to eq 'OK'
15
+ expect(subject[:categories]).to have(18).items
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'when error' do
21
+ subject { client.get('categories/999999999', geo_id: 225) }
22
+
23
+ it do
24
+ VCR.use_cassette 'get_category_with_invalid_id' do
25
+ expect { subject }.to raise_error(Apress::YandexMarket::Api::Error, '404 - Category 999999999 not found')
26
+ end
27
+ end
28
+ end
29
+
30
+ context 'when error with html body' do
31
+ let(:error_body) do
32
+ '<html><body><h1>502 Bad Gateway</h1>The server returned an invalid or incomplete response.</body></html>'
33
+ end
34
+
35
+ subject { client.get('example') }
36
+
37
+ before do
38
+ stub_request(:get, 'https://api.content.market.yandex.ru/v2/example').to_return(status: 502, body: error_body)
39
+ end
40
+
41
+ it do
42
+ expect { VCR.turned_off { subject } }.to raise_error(Apress::YandexMarket::Api::Error, '502 - ')
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Apress::YandexMarket::Readers::Category do
4
+ let(:categories) { 'Авто; Красота' }
5
+ let(:reader) { described_class.new(token: 'secret_token', categories: categories) }
6
+
7
+ describe '.allowed_options' do
8
+ it { expect(described_class.allowed_options).to eq %i(token region_id categories) }
9
+ end
10
+
11
+ describe '#each_row' do
12
+ let(:rows) { [] }
13
+
14
+ context 'when no errors' do
15
+ before do
16
+ VCR.use_cassette 'read_two_categories' do
17
+ reader.each_row { |row| rows << row }
18
+ end
19
+ end
20
+
21
+ it 'reads specified categories and their subcategories' do
22
+ expect(rows).to have(326).items
23
+ expect(rows.map { |row| row[:name] }).to include('Авто', 'Красота') # корневые категории
24
+ expect(rows.map { |row| row[:name] }).
25
+ to include('Авто', 'Запчасти', 'Фильтры', 'Воздушные фильтры') # поддерево от корня до листа
26
+ end
27
+ end
28
+
29
+ context 'when page error' do
30
+ before do
31
+ allow(reader.client).to receive(:get).and_call_original
32
+ allow(reader.client).to receive(:get).with('categories/90509/children', anything).
33
+ and_raise(Apress::YandexMarket::Api::PageError)
34
+
35
+ VCR.use_cassette 'read_two_categories_with_page_error' do
36
+ reader.each_row { |row| rows << row }
37
+ end
38
+ end
39
+
40
+ it 'reads specified categories and their subcategories' do
41
+ expect(rows).to have(187).items
42
+ expect(rows.map { |row| row[:name] }).to include('Авто', 'Красота')
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Apress::YandexMarket::Readers::ModelByCategory do
4
+ let(:categories) { 'Красота' } # id: 90509
5
+ let(:reader) { described_class.new(token: 'secret_token', categories: categories) }
6
+
7
+ describe '.allowed_options' do
8
+ it { expect(described_class.allowed_options).to eq %i(token region_id categories) }
9
+ end
10
+
11
+ describe '#each_row' do
12
+ let(:rows) { [] }
13
+
14
+ before do
15
+ allow(reader.category_reader.client).to receive(:get).and_call_original
16
+ allow(reader.category_reader.client).to receive(:get).with('categories/90509/children', anything).
17
+ and_return(categories: [{id: 8_476_099, childCount: 0}])
18
+
19
+ VCR.use_cassette 'read_models_from_category' do
20
+ reader.each_row { |row| rows << row }
21
+ end
22
+ end
23
+
24
+ it 'reads models of specified categories and their subcategories' do
25
+ expect(rows).to have(840).items
26
+ expect(rows.uniq).to have(840).items
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,81 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.content.market.yandex.ru/v2/categories/999999999?geo_id=225
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Host:
17
+ - api.content.market.yandex.ru
18
+ Authorization:
19
+ - some_secret_token
20
+ response:
21
+ status:
22
+ code: 404
23
+ message: Not Found
24
+ headers:
25
+ Date:
26
+ - Thu, 01 Nov 2018 13:45:22 GMT
27
+ Content-Type:
28
+ - application/json;charset=utf-8
29
+ X-Request-Id:
30
+ - h9672x1101cf7fc849
31
+ X-Market-Req-Id:
32
+ - 1541079922406/bff948421ff4ffc38c089609f84b44cb
33
+ X-Region-Id:
34
+ - '225'
35
+ X-Ratelimit-Method-Limit:
36
+ - '100'
37
+ X-Ratelimit-Method-Remaining:
38
+ - '99'
39
+ X-Ratelimit-Method-Until:
40
+ - Thu, 01 Nov 2018 13:45:23 GMT
41
+ X-Ratelimit-Global-Limit:
42
+ - '2'
43
+ X-Ratelimit-Global-Remaining:
44
+ - '1'
45
+ X-Ratelimit-Global-Until:
46
+ - Thu, 01 Nov 2018 13:45:23 GMT
47
+ X-Ratelimit-Daily-Limit:
48
+ - '1000000000'
49
+ X-Ratelimit-Daily-Remaining:
50
+ - '999999508'
51
+ X-Ratelimit-Daily-Until:
52
+ - Fri, 02 Nov 2018 00:00:00 GMT
53
+ Content-Language:
54
+ - en-US
55
+ Cache-Control:
56
+ - no-store
57
+ Set-Cookie:
58
+ - i=nkVwTF0E65LH4sm4NpHIg5atL/I/faA0FmAPCndzPTcPoUFHMQZ6uan3HuO9B80ZasE1jpwvJexdt/1tRFSNHb9nnCk=;
59
+ Expires=Sun, 29-Oct-2028 13:45:22 GMT; Domain=.yandex.ru; Path=/; Secure;
60
+ HttpOnly
61
+ - uid=AAAihFvbA3KyYgE+BT9sAg==; path=/
62
+ Strict-Transport-Security:
63
+ - max-age=31536000
64
+ Transfer-Encoding:
65
+ - chunked
66
+ body:
67
+ encoding: ASCII-8BIT
68
+ string: !binary |-
69
+ eyJzdGF0dXMiOiJFUlJPUiIsImNvbnRleHQiOnsicmVnaW9uIjp7ImlkIjoy
70
+ MjUsIm5hbWUiOiLQoNC+0YHRgdC40Y8iLCJ0eXBlIjoiQ09VTlRSWSIsImNo
71
+ aWxkQ291bnQiOjEwLCJjb3VudHJ5Ijp7ImlkIjoyMjUsIm5hbWUiOiLQoNC+
72
+ 0YHRgdC40Y8iLCJ0eXBlIjoiQ09VTlRSWSIsImNoaWxkQ291bnQiOjEwfX0s
73
+ ImN1cnJlbmN5Ijp7ImlkIjoiUlVSIiwibmFtZSI6ItGA0YPQsS4ifSwiaWQi
74
+ OiIxNTQxMDc5OTIyNDA2L2JmZjk0ODQyMWZmNGZmYzM4YzA4OTYwOWY4NGI0
75
+ NGNiIiwidGltZSI6IjIwMTgtMTEtMDFUMTY6NDU6MjIuNDErMDM6MDAiLCJt
76
+ YXJrZXRVcmwiOiJodHRwczovL21hcmtldC55YW5kZXgucnU/cHA9MTAwMSZj
77
+ bGlkPTIzMjY2MDEmZGlzdHJfdHlwZT03In0sImVycm9ycyI6W3sibWVzc2Fn
78
+ ZSI6IkNhdGVnb3J5IDk5OTk5OTk5OSBub3QgZm91bmQifV19
79
+ http_version:
80
+ recorded_at: Thu, 01 Nov 2018 13:44:52 GMT
81
+ recorded_with: VCR 4.0.0
@@ -0,0 +1,82 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.content.market.yandex.ru/v2/categories?count=30&geo_id=225
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Host:
17
+ - api.content.market.yandex.ru
18
+ Authorization:
19
+ - some_secret_token
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Mon, 24 Dec 2018 14:10:52 GMT
27
+ Content-Type:
28
+ - application/json;charset=utf-8
29
+ X-Request-Id:
30
+ - v4739x1224e089d5f0
31
+ X-Market-Req-Id:
32
+ - 1545660652508/11de5b809782bd8b8b4921f259e5bae2
33
+ X-Region-Id:
34
+ - '225'
35
+ X-Ratelimit-Method-Limit:
36
+ - '100'
37
+ X-Ratelimit-Method-Remaining:
38
+ - '99'
39
+ X-Ratelimit-Method-Until:
40
+ - Mon, 24 Dec 2018 14:10:53 GMT
41
+ X-Ratelimit-Global-Limit:
42
+ - '2'
43
+ X-Ratelimit-Global-Remaining:
44
+ - '1'
45
+ X-Ratelimit-Global-Until:
46
+ - Mon, 24 Dec 2018 14:10:53 GMT
47
+ X-Ratelimit-Daily-Limit:
48
+ - '1000000000'
49
+ X-Ratelimit-Daily-Remaining:
50
+ - '999997022'
51
+ X-Ratelimit-Daily-Until:
52
+ - Tue, 25 Dec 2018 00:00:00 GMT
53
+ Set-Cookie:
54
+ - i=9aI1w1reokMFM7TMMP4ppKWfu6YJf7jNGgKKpRqkF/l9nNpIMedEGcsqFZ1VsoOxgRMQPl/HH/1alGV5pMG3DgLJaJs=;
55
+ Expires=Thu, 21-Dec-2028 14:10:52 GMT; Domain=.yandex.ru; Path=/; Secure;
56
+ HttpOnly
57
+ - uid=AAAihFwg6OwlVgDIBCM0Ag==; path=/
58
+ Strict-Transport-Security:
59
+ - max-age=31536000
60
+ Transfer-Encoding:
61
+ - chunked
62
+ body:
63
+ encoding: UTF-8
64
+ string: '{"status":"OK","context":{"region":{"id":225,"name":"Россия","type":"COUNTRY","childCount":10,"country":{"id":225,"name":"Россия","type":"COUNTRY","childCount":10}},"currency":{"id":"RUR","name":"руб."},"page":{"number":1,"count":18,"total":1},"id":"1545660652508/11de5b809782bd8b8b4921f259e5bae2","time":"2018-12-24T17:10:52.512+03:00","marketUrl":"https://market.yandex.ru?pp=1001&clid=2326601&distr_type=7"},"categories":[{"id":90402,"name":"Авто","fullName":"Товары
65
+ для авто- и мототехники","link":"https://market.yandex.ru/catalog--tovary-dlia-avto-i-mototekhniki/90402/list?hid=90402&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":12,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90509,"name":"Красота","fullName":"Товары
66
+ для красоты","link":"https://market.yandex.ru/catalog--tovary-dlia-krasoty/90509/list?hid=90509&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":3,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90666,"name":"Товары
67
+ для дома","fullName":"Товары для дома","link":"https://market.yandex.ru/catalog--tovary-dlia-doma/90666/list?hid=90666&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":9,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90719,"name":"Дача,
68
+ сад и огород","fullName":"Дача, сад и огород","link":"https://market.yandex.ru/catalog--dacha-sad-i-ogorod/90719/list?hid=90719&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":13,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90764,"name":"Детские
69
+ товары","fullName":"Детские товары","link":"https://market.yandex.ru/catalog--detskie-tovary/90764/list?hid=90764&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":6,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90801,"name":"Досуг
70
+ и развлечения","fullName":"Досуг и развлечения","link":"https://market.yandex.ru/catalog--dosug-i-razvlecheniia/90801/list?hid=90801&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":14,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":90813,"name":"Товары
71
+ для животных","fullName":"Товары для животных","link":"https://market.yandex.ru/catalog--tovary-dlia-zhivotnykh/90813/list?hid=90813&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":29,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91009,"name":"Компьютерная
72
+ техника","fullName":"Компьютерная техника","link":"https://market.yandex.ru/catalog--kompiuternaia-tekhnika/91009/list?hid=91009&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":12,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91307,"name":"Продукты","fullName":"Продукты,
73
+ напитки","link":"https://market.yandex.ru/catalog--produkty-napitki/91307/list?hid=91307&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":14,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91512,"name":"Спорт
74
+ и отдых","fullName":"Товары для спорта и отдыха","link":"https://market.yandex.ru/catalog--tovary-dlia-sporta-i-otdykha/91512/list?hid=91512&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":17,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91597,"name":"Строительство
75
+ и ремонт","fullName":"Товары для строительства и ремонта","link":"https://market.yandex.ru/catalog--tovary-dlia-stroitelstva-i-remonta/91597/list?hid=91597&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":7,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":198119,"name":"Электроника","fullName":"Электроника","link":"https://market.yandex.ru/catalog--elektronika/198119/list?hid=198119&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":7,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":198118,"name":"Бытовая
76
+ техника","fullName":"Бытовая техника","link":"https://market.yandex.ru/catalog--bytovaia-tekhnika/198118/list?hid=198118&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":6,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91735,"name":"Услуги","fullName":"Услуги","link":"https://market.yandex.ru/catalog--uslugi/91735/list?hid=91735&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":11,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":91763,"name":"Оборудование","fullName":"Оборудование","link":"https://market.yandex.ru/catalog--oborudovanie/91763/list?hid=91763&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":16,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":15807107,"name":"Услуги
77
+ по подписке","fullName":"Услуги по подписке","link":"https://market.yandex.ru/catalog--uslugi-po-podpiske/15807107/list?hid=15807107&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":0,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":8475840,"name":"Здоровье","fullName":"Товары
78
+ для здоровья","link":"https://market.yandex.ru/catalog--tovary-dlia-zdorovia/8475840/list?hid=8475840&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":15,"advertisingModel":"HYBRID","viewType":"LIST"},{"id":7877999,"name":"Одежда,
79
+ обувь и аксессуары","fullName":"Одежда, обувь и аксессуары","link":"https://market.yandex.ru/catalog--odezhda-obuv-i-aksessuary/7877999/list?hid=7877999&onstock=1&pp=1001&clid=2326601&distr_type=7","childCount":5,"advertisingModel":"HYBRID","viewType":"LIST"}]}'
80
+ http_version:
81
+ recorded_at: Mon, 24 Dec 2018 14:10:02 GMT
82
+ recorded_with: VCR 4.0.0