Мониторинг категорий
Отслеживание цен конкурентов в категориях.
Хендлеры
@fp.router.on_lot_category()
Следит за обычными лотами. Срабатывает когда меняется цена или топ-1 в отслеживаемых категориях. Твои собственные лоты игнорируются.
from fpx import types
@fp.router.on_lot_category()
async def lot_changed(lot: types.CategoryLastLot):
print(f'Конкурент {lot.owner_username} перебил цену до {lot.price}')
@fp.router.on_chip_category()
То же самое для чипсов (игровая валюта).
@fp.router.on_chip_category()
async def chip_changed(lot: types.CategoryLastLot):
print(f'Чипсы: {lot.offer_id} = {lot.price}')
Запуск мониторинга
Чтобы хендлеры срабатывали, нужно передать watch_lots и/или watch_chips в start_polling:
await fp.runner.start_polling(
3,
is_background=True,
watch_lots=[1316, 99], # ID категорий лотов
watch_chips=[55] # ID категорий чипсов
)
Объект CategoryLastLot
| Поле | Тип | Описание |
|---|---|---|
category_id |
str |
ID категории |
filtration |
str |
Название фильтра |
price |
float |
Цена лота |
offer_id |
str |
ID лота |
owner_username |
str |
Ник продавца |
CategoryManager (через account.category)
await fp.account.category.get_lot_category_last_lot(category_id)
Возвращает самый дешёвый лот по каждому фильтру в категории.
lots = await fp.account.category.get_lot_category_last_lot(1316)
for lot in lots:
print(f'{lot.filtration}: {lot.price} у {lot.owner_username}')
Возвращает list[CategoryLastLot].
await fp.account.category.get_chip_category_last_lot(category_id)
То же самое для чипсов.
Работа со всеми категориями
Оба метода возвращают список игр с подкатегориями. Внутренняя структура одинаковая.
await fp.account.category.get_all_categories()
Собирает все категории с главной страницы FunPay.
Парсит HTML, полученный через get_main_menu().
games = await fp.account.category.get_all_categories()
for game in games:
print(f'{game.title.name} (id={game.title.id})')
for sub in game.subcategories:
print(f' └ {sub.sub_name} (id={sub.id})')
Возвращает: list[Game]
Raises: FpxRequestError - при ошибке запроса.
await fp.account.category.find_category(target)
Ищет категории через встроенный поиск FunPay.
target: str - слово или фраза для поиска. Допускает погрешности (нечёткий поиск на стороне фп).
results = await fp.account.category.find_category('minecraft')
for game in results:
print(game.title.name, [s.sub_name for s in game.subcategories])
Возвращает: list[Game]
Raises: FpxRequestError - при ошибке запроса.
Вложенная структура: Game → GameTitle + GameSubCategory
Оба новых метода list[Game]. Внутри два уровня вложенности.
Game
├── title: GameTitle
│ ├── id: int — ID игры (число, не строка)
│ └── name: str — название игры
└── subcategories: list[GameSubCategory]
└── GameSubCategory
├── id: int — ID подкатегории
└── sub_name: str — название подкатегории
Game - контейнер: хранит саму игру (title) и список её подкатегорий.
GameTitle - идентификатор игры.
GameSubCategory — подкатегория внутри игры. Например, "Аккаунты", "Пополнение", "Услуги" и т.д. У каждой свой id.
Пример:
games = await fp.account.category.get_all_categories()
# Достаём первую игру
first = games[0]
print(first.title.name) # "Minecraft"
print(first.title.id) # 42
print(first.subcategories[0].sub_name) # "Аккаунты"
print(first.subcategories[0].id) # 1316
# Обходим всё
for game in games:
print(f'\n{game.title.name}:')
for sub in game.subcategories:
print(f' [{sub.id}] {sub.sub_name}')
Альтернативный доступ через fpx.services
```python from fpx.services import CategoryManager
category_mgr = CategoryManager(fp.account) lots = await category_mgr.get_lot_category_last_lot(1316)