A Python API client for Perekrestok catalog
Project description
Perekrestok API (not official)
Perekrestok (Перекрёсток) - https://www.perekrestok.ru/
Принцип работы
Библиотека полностью повторяет сетевую работу обычного пользователя на сайте. Основная логика сетевых запросов заложена в
api.py, она управляетсяPerekrestokAPI()вmanager.py. Существует вспомогательный модульabstraction.pyхранящий в себе статичные классы, которых принимаю в аргументах некоторые методы вPerekrestokAPI().
Usage / Использование
Базовая структура
import asyncio
from perekrestok_api import PerekrestokAPI, ABSTRACT
async def main():
...
if __name__ == "__main__":
asyncio.run(main())
Работа с геолокацией в сессии:
От геолокации и способа получения (доставка/забрать из магазина) зависит выдача каталога!
async with PerekrestokAPI(
debug = False, # Включить ли логирование библиотеки
token_retry_attempts = 3 # Количество попыток авторизации
) as Api:
geopos_handler = await Api.Geolocation.current()
geopos = geopos_handler.response
print(f'Текущий город сессии {geopos["content"]["city"]["name"]} ({geopos["content"]["city"]["id"]})')
# Ищем геолокацию города по названию
content_handler = await Api.Geolocation.search("нижневартовск")
content = content_handler.response
# Ищем магазины в этом городе
point_in_city_handler = await Api.Geolocation.Shop.on_map(
# Мы можем выбрать магазины на карте через геопозицию
position=ABSTRACT.Geoposition(content['content']['items'][0]['location']['coordinates']),
# Или через ID населенного пункта (особой разницы нет). Эти параметры не противоречат друг другу.
city_id=content['content']['items'][0]['id'],
# Количество магазинов в ответе
limit=3,
# Фильтр особенностей магазина, `4` - это кофепоинт
# С актуальным списком "особенностей" для магазинов можно ознакомиться в `await Api.Geolocation.Shop.features()`
features=[4],
# Сортировка как "самый ближайший"
sort=ABSTRACT.GeologicationPointSort.Distance.ASC
)
point_in_city = point_in_city_handler.response
# Выбираем первый (по сути центральный, т.к. сортировка по удалению от конкретной точки)
shop_handler = await Api.Geolocation.Selection.shop(point_in_city['content']['items'][0]['id'])
shop = shop_handler.response
print(f'Выбран магазин \"{shop["content"]["shop"]["title"]}\", по адресу {shop["content"]["shop"]["address"]}')
# Теперь можем проверить, действительно ли сменили геолокацию
geopos_handler = await Api.Geolocation.current()
geopos = geopos_handler.response
print(f'Текущий город сессии {geopos["content"]["city"]["name"]} ({geopos["content"]["city"]["id"]})')
> Текущий город сессии Москва (81)
> Выбран магазин "ТЦ Green Park", по адресу Ханты-Мансийский Автономный округ - Югра, г Нижневартовск, ул Ленина, зд 8
> Текущий город сессии Нижневартовск (73)
Взаимодействие с каталогом
async with PerekrestokAPI() as Api:
# Получение дерева категорий каталога
tree_handler = await Api.Catalog.tree()
tree = tree_handler.response
# Список для хранения всех обработанных товаров
products = []
# Прогресс-бар для отображения процесса обработки
tq = tqdm.tqdm(tree["content"]["items"], desc='Обработано категорий')
# Рекурсивная функция для обработки категорий и их подкатегорий
async def process_sub(tree_items, depth=0):
# Используем прогресс-бар только на верхнем уровне вложенности
current_level = tq if depth == 0 else tree_items
for category_group in current_level:
category = category_group["category"]
# Формирование фильтра для запроса каталога
feed_filter = ABSTRACT.CatalogFeedFilter()
feed_filter.CATEGORY_ID = category["id"]
# Запрашиваем товары из текущей категории
catalog_handler = await Api.Catalog.feed(filter=feed_filter)
catalog = catalog_handler.response
page = 1
# Цикл обработки всех страниц товаров в категории
while page > 0 and len(catalog["content"]["items"]) > 0:
for product in catalog["content"]["items"]:
# Сохраняем название и ID товара
products.append(f'{product["title"]} ({product["id"]})')
tq.desc = f'Обработано карточек: {len(products)}'
# Переход к следующей странице или завершение обработки
if catalog['content']['paginator']['nextPageExists']:
page += 1
catalog_handler = await Api.Catalog.feed(filter=feed_filter, page=page)
catalog = catalog_handler.response
else:
page = -1
# Рекурсивно обрабатываем подкатегории
for child in category_group.get("children", []):
await process_sub([child], depth + 1)
# Запуск обработки дерева категорий
await process_sub(tree["content"]["items"])
# Вывод итоговой статистики
print(f'Общее количество встреченных карточек: {len(products)}')
print(f'Уникальных товаров: {len(set(products))}')
print(f'Среднее количество повторений карточки: {round(len(products) / len(set(products)), 2)}')
> Обработано карточек: 41620: 100%|█████████████████████████| 29/29 [03:56<00:00, 8.15s/it]
> Общее количество встреченных карточек: 41620
> Уникальных товаров: 17630
> Среднее количество повторений карточки: 2.36
Загрузка изображений
async with PerekrestokAPI() as Api:
img = await Api.General.download_image("https://cdn-img.perekrestok.ru/i/400x400-fit/xdelivery/files/ae/2a/4f39b2a249768b268ed9f325c155.png")
with open(img.name, "wb") as f:
f.write(img.read())
Или параллельная загрузка
async with PerekrestokAPI() as Api:
tasks = [
Api.General.download_image("https://cdn-img.perekrestok.ru/i/400x400-fit/xdelivery/files/ae/2a/4f39b2a249768b268ed9f325c155.png"),
Api.General.download_image("https://cdn-img.perekrestok.ru/i/400x400-fit/xdelivery/files/ae/2a/4f39b2a249768b268ed9f325c155.png")
]
results = await asyncio.gather(*tasks)
for result in results:
with open(result.name, "wb") as f:
f.write(result.read())
Report / Обратная связь
If you have any problems using it / suggestions, do not hesitate to write to the project's GitHub!
Если у вас возникнут проблемы в использовании / пожелания, не стесняйтесь писать на GitHub проекта!
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file perekrestok_api-0.1.6.tar.gz.
File metadata
- Download URL: perekrestok_api-0.1.6.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebbab1f6a322fdacadf422f317af7f225dea2d35c9aab5946d049a3cec9cec02
|
|
| MD5 |
c0ca1d922a90124b089f1ba9182fd656
|
|
| BLAKE2b-256 |
6a8cfd3b5a08ec4bc6e3fd2ff88067a1583f096575347ab7e8ff95a058983d04
|
Provenance
The following attestation bundles were made for perekrestok_api-0.1.6.tar.gz:
Publisher:
python-publish.yml on Open-Inflation/perekrestok_api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
perekrestok_api-0.1.6.tar.gz -
Subject digest:
ebbab1f6a322fdacadf422f317af7f225dea2d35c9aab5946d049a3cec9cec02 - Sigstore transparency entry: 245876207
- Sigstore integration time:
-
Permalink:
Open-Inflation/perekrestok_api@9500221956c94afb26035ef836e8cc229d38377b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Open-Inflation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9500221956c94afb26035ef836e8cc229d38377b -
Trigger Event:
push
-
Statement type:
File details
Details for the file perekrestok_api-0.1.6-py3-none-any.whl.
File metadata
- Download URL: perekrestok_api-0.1.6-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ef465a185b71cd34bdd25a6a5632589c25804feaccfd20d492b9435b52fda4a
|
|
| MD5 |
5acac08bc68bd857e3588a72f845e2e2
|
|
| BLAKE2b-256 |
f8e129211e9d00471526cb331ad9a612fe6bbe07a1a1f23f080d3033e899cba6
|
Provenance
The following attestation bundles were made for perekrestok_api-0.1.6-py3-none-any.whl:
Publisher:
python-publish.yml on Open-Inflation/perekrestok_api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
perekrestok_api-0.1.6-py3-none-any.whl -
Subject digest:
2ef465a185b71cd34bdd25a6a5632589c25804feaccfd20d492b9435b52fda4a - Sigstore transparency entry: 245876211
- Sigstore integration time:
-
Permalink:
Open-Inflation/perekrestok_api@9500221956c94afb26035ef836e8cc229d38377b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Open-Inflation
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9500221956c94afb26035ef836e8cc229d38377b -
Trigger Event:
push
-
Statement type: