Как возможно реализовать чекер незанятых юзернеймов в телеграмме?
Нужно сделать чекер незанятых юзернеймов в телеграмме. Если использовать Telethon и pyrogram, то будет неточность (если ник некорректный, то будет писать что он свободен) + флуд бан на час/ сутки. Запрос по ссылке «t.me/. » не работает, т.к. даже если человека с таким юзернеймом не существует, то все равно будет кнопка, чтобы написать ему (ника может не быть, но юзернейм все равно занят). Пробовал через селениум в настройках вводить ник и чекать сообщение, но после 200 попыток будет выводить, что ник занят, даже если он свободен. Так же писал @username_bot и кидал ему ники, там уже работает телеграмм флуд защита и сообщения перестают отправляться.
Отслеживать
задан 15 июн в 11:07
48 6 6 бронзовых знаков
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Для того чтобы решить данную проблему нужно использовать библиотеку Telethon и два метода: client.get_entity() и client(functions.account.CheckUsernameRequest), так же для того чтобы избежать Floodwaiterror нужно использовать более 10 аккаунтов и чередовать их.
Отслеживать
ответ дан 23 июн в 17:46
48 6 6 бронзовых знаков
- python
- telegram
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.15.1019
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Пишем свой чекер аккаунтов на Python
⚠️ Дисклеймер Статья написана с познавательной и ознакомительной целью, мы не призываем читателей к запрещенным законодательством действиям, а также не создаём пропаганду. Мы никого ни к чему не призываем! Вся информация представленная нами — это фантазия автора, выдумка, сон, вымысел. Данный материал не имеет ни какого отношения к реальности, все совпадения — случайность. Автор материала не несёт ответственности за ваши действия. Все персонажи и описываемые события являются вымышленными.
Итак, сегодня мы будем писать чекер аккаунтов. Чтобы не было никакой рекламы, писать чекер мы будем на свой сайт.
Внимание: этот гайд для новичков, если вы уже знаете как работать с requests, тут ничего полезного для вас не будет (наверное)
Что нам необходимо:
- Python 3 (Желательно последней версии) — скачать
- Редактор кода, например PyCharm , VS Code , Notepad++
- Свой сайт — скачать исходники , exe , VT
- Библиотека requests — pip install requests
- Минимальные знания Python и прямые руки
Для начала запускаем сервер, он нам даст адрес нашего сайта:
Переходим на сайт и видим форму входа
У нас есть 2 пользователя:
Теперь мы можем начинать писать наш чекер, создаем новый файл с окончанием .py и добавляем нужный нам импорт:
import requests
База аккаунтов у нас будет в файле logins.txt , создаём её (не обязательно переписывать всё, просто добавьте аккаунты по вкусу):
Далее нам надо эту базу прочитать, для этого откроем файл через open:
file = open('logins.txt').read()
Но это только прочитает файл, а нам надо ещё разделить аккаунты по строкам, для этого используем .split(‘\n’), который разделит файл:
Теперь переходим в браузер, я буду показывать на примере Google Chrome. Открываем наш сайт и нажимаем Ctrl + Shift + I, и переходим в вкладку Network, и нажимаем на флажок Preserve log
Далее вводим верный логин и пароль и нажимаем Войти, у нас во вкладке Network появится новый запрос
Нажимаем на него и видим такую картину
Смотрим в Request Headers, нас интересует Content-Type. У нас это application/x-www-form-urlencoded. Он может быть и application/json. Мы будем делать всё на примере application/x-www-form-urlencoded. JSON рассмотрим уже во второй части. Теперь смотрим в Form Data и видим поля login и password. Теперь мы можем приступить к написанию кода. Т.к. у нас POST запрос, мы будем использовать requests.post и ссылку из Request URL:
requests.post("http://127.0.0.1:5000/login")
Далее нам надо передать наш логин и пароль, для этого добавляем после URL, data=<>:
requests.post("http://127.0.0.1:5000/login", data=<>)
Теперь в <> пишем поля из Form Data:
Для получения ответа сервера необходимо добавить .text в конец строки. В итоге:
requests.post("http://127.0.0.1:5000/login", data=).text
Кидаем это всё в print и смотрим результат. Если вы всё сделали правильно, то будет такое:
Теперь мы можем добавить проверку на успешный вход и получение баланса:
login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(balance) else: # Пароль не верный print("Не валидный аккаунт")
Итак, время проверять наши аккаунты! Для этого добавляем цикл перебора всех аккаунтов и с помощью .split(«:») делим базу на логин и пароль. Добавляем наши переменные в запрос и добавляем выводы:
for account in file: username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ")
Запускаем и видим, что наши аккаунты прочекались:
import requests # Читаем file = open('logins.txt').read().split('\n') # Чекаем все аккаунты for account in file: username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ")
Потоки
Чекер слишком долго проверяет аккаунты? Это время добавить потоки, которые будут проверять аккаунты не зависимо друг от друга. Для этого мы будем использовать библиотеку threading — она уже есть в Python. Добавляем её:
import threading
Теперь нам надо написать функцию проверки аккаунта, просто вносим весь код в неё:
def check(account): username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ")
Теперь нам нужна функция для самого потока, которая будет брать аккаунт и проверять его:
def thread(): # Пока есть аккаунты while file: # Берём первый аккаунт из списка to_check = file[0] # Удаляем его из списка file.remove(to_check) try: # Вызываем функцию проверки аккаунта check(to_check) except Exception as e: # Если что-то пойдет не так, выведет ошибку print("Ошибка:", e)
Добавляем переменную thread_count, в которой мы будем указывать количество потоков:
thread_count = 10
Итак, базу мы написали. Теперь можно писать запуск потоков:
# Запускаем thread_count потоков for _ in range(thread_count): # Создаем наш поток. В target передаем нашу функцию. ВНИМАНИЕ: Функцию надо указывать без (), иначе мы передадим не саму функцию, а её ответ. t = threading.Thread(target=thread) # Запускаем поток t.start()
Запускаем и смотрим как быстро отработал наш чекер
import threading import requests # Читаем file = open('logins.txt').read().split('\n') thread_count = 10 def thread(): # Пока есть аккаунты while file: # Берём первый аккаунт из списка to_check = file[0] # Удаляем его из списка file.remove(to_check) try: # Вызываем функцию проверки аккаунта check(to_check) except Exception as e: # Если что-то пойдет не так, выведет ошибку print("Ошибка:", e) # Перебираем все аккаунты def check(account): username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ") # Запускаем thread_count потоков for _ in range(thread_count): # Создаем наш поток. В target передаем нашу функцию. ВНИМАНИЕ: Функцию надо указывать без (), иначе мы передадим не саму функцию, а её ответ. t = threading.Thread(target=thread) # Запускаем поток t.start()
Запись в файл
Вывод в консоль не самый удобный метод. Надо писать валидные аккаунты в файл. Для этого мы будем использовать open(), но с некоторыми различиями. Чтобы открыть файл на запись нам нужен режим a+, где a — append (добавлять к файлу) и + — создание файла если его нет.
Пример:
open('файл', 'a+').write("текст")
В нашем случае мы будем писать гуды в файл good.txt . Для этого, чтобы не открывать его кучу раз используем (не забывая в конце закрыть файл через .close()):
goods = open('good.txt', 'a+')
Рядом с print пишем саму запись в файл:
goods.write(f":\n")
\n в конце — это перенос строки в файле. Добавляем это рядом с print (или вместо его). Запускаем код и смотрим в файл good.txt :
Наши валидные аккаунты записались в файл
import requests # Читаем file = open('logins.txt').read().split('\n') goods = open('good.txt', 'a+') # Чекаем все аккаунты for account in file: username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] goods.write(f":\n") print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ")
Прокси
Последняя тема, которую мы разберём в данном уроке — прокси. Чекер без прокси долго работать не будет. Читать прокси мы будем аналогично аккаунтам:
proxies = open('proxy.txt').read().split('\n')
Прокси должны начинаться с протокола, например https:// или socks5://. Можно добавить протокол в сам код или прямо в файл с листом прокси. Выбираем рандомный прокси:
proxy = random.choice(proxies)
Чтобы использовать прокси в запросах, надо их передать. Добавляем после data=<> запятую и пишем
proxies=dict(http=proxy, https=proxy)
random.choice выберет рандомный прокси из нашего списка. Его так-же надо импортировать:
import random
Чтобы работать с socks надо установить pysocks:
pip install pysocks
Внимание: если вы работаете с локальным сервером, прокси не будут работать. Выглядеть код должен примерно так:
requests.post("http://127.0.0.1:5000/login", data=, proxies=dict(http=proxy, https=proxy)).text
import random import requests # Читаем file = open('logins.txt').read().split('\n') proxies = open('proxy.txt').read().split('\n') # Чекаем все аккаунты for account in file: proxy = random.choice(proxies) username = account.split(":")[0] password = account.split(":")[1] login = requests.post("http://127.0.0.1:5000/login", data=, proxies=dict(http=proxy, https=proxy)).text # Проверяем верный ли пароль if not "Не верный пароль" in login: # Пароль верный, получаем баланс balance = login.split("У Вас ")[1].split(" ")[0] print(f"Валидный аккаунт с балансом рублей") else: # Пароль не верный print(f"Не валидный аккаунт ")
Lua Python Hermer — Чекер | Авто-Выставление на продажу Samp-Store
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно.
Вам необходимо обновить браузер или попробовать использовать другой.
Haymiritch
Известный
Автор темы
- Другая
Авто проверка (чекер) аккаунтов SAMP для игрового сервера Arizona RP. Менеджер аккаунтов. Авто выставление аккаунта на продажу.
Данный скрипт облегчит вам проверку аккаунтов что-бы выставить их на продажу на Samp-Store, поможет просматривать статистику.
На данный момент доступен только 1 сервер: Arizona RP.
Требования:
RakSAMP Lite (последней версии), samp.lua (идет вместе с раксампом), addon (тоже идёт вместе с раксампом), inicfg для раксампа
Python 3.9 или выше. Библиотеки: requests, configparser
Установка:
RakSAMP Lite: Установить все нужные библиотеки, файл «Arizona_Checker.lua» перекинуть в папку script которая в корневой папке раксампа. Создать папку «checker» в корневой папке раксампа.
Python скрипт: Перекинуть в папку «checker» main.py, hermer.ini. Создать папку accs.
Запуск:
Открыть командную строку, перейти в папку с чекером (python скрипт), прописать main.py. Запустится этот скрипт, в первой вкладке настройки настраиваем чекер. Готово.
Спойлер: Скриншот скрипта
Спойлер: Функции на данный момент
Настройки (samp-store api key, директория раксампа)
Загрузить аккаунты для чека с Samp-Store
Чекер аккаунтов (с самп стора, с текстовика)
Менеджер аккаунтов (самп стор)
Менеджер кастомоных аккаунтов (с текстовика которые)
Чекер работает только на Arizona RP.
Как написать чекер на python
![]()
Hepic_Antony_Skarlatos → How old are you ?
n0sk1ll → Codeforces Round #910 (Div. 2)
molney → Разбор Codeforces Round 909 (Div. 3)
MahaRathi → What’s wrong in my solution?
Medeali → Finally Pupil
n0sk1ll → Editorial for Codeforces Round #910 (Div. 2)
Little_Sheep_Yawn → Help Needed for this Pypy Issue!
IanDeHaan → Invitation to the Alberta Collegiate Programming Contest 2023 (Open Division)
killmeray → VK — огромная проблема олимпиад
glebustim → CodeTON Round 6 (Div. 1 + Div. 2, Rated, Prizes!)
k o_osaga → T1 is the 2023 World Champion
ICPCNews → ICPC 2023 Online Challenge powered by Huawei
![]()
pritishn → Share your big brain moments from back when you were low rated.
av.dk → Div3 round 909
atcoder_official → Sky Inc, Programming Contest 2023 (AtCoder Beginner Contest 329) Announcement
T LE → Finally, semantic search for competitive programming problems
pingvvin → I need IZHO 2011 Editorial
![]()
MikeMirzayanov → Изменение правил об использовании стороннего кода в соревнованиях Codeforces
m aroonrk → ALGO ARTIS Programming Contest 2023 Autumn(AtCoder Regular Contest 168) Announcement
zwezdinv → Codeforces Round #909 (Div. 3)
Rahat_Khan_Pathan → Solve UVa 11235 — Frequent values using Segment Tree
Mahmyt → IZHO age limit
AcidWrongGod → Открытая Командная Олимпиада КФУ 2023
libnguyen2 → [Discussion]: Solutions for IOI 2023 tasks + My solution to IOI23 Day1 P1 — Closing Time
sg0310461 → Why this solution is giving TLE?
Блог пользователя MikeMirzayanov
Автор MikeMirzayanov, 13 лет назад ,

Библиотека testlib.h
Здесь пойдет речь о библиотеке testlib.h, которая была написана мной достаточно давно — году в 2005-ом. Незадолго до этого было объявлено об отказе на финале ACM-ICPC от использования Pascal, популярность набирал TopCoder (где так же нет Pascal/Delphi). Все это приводило к мыслям, что писать чекеры на Pascal вечно невозможно, да и не всегда достаточно удобно, да и кроссплатформенным этот вариант назвать трудно — по-моему далеко не все testlib.pas (которых несколько разновидностей) компилируются free pascal.
Про чекеры
Так как не все читатели являются авторами задач, то давайте проясним смысл этого слова. Чекером называется программа, которая читает входной файл (тест), вывод проверяемой программы, предполагаемый ответ и выводит вердикт относительно корректности вывода проверяемой программы. Обычно, бывают следующие вердикты: OK (ответ верен, представлен один из правильных ответов), WA (ответ неверен), PE (формат вывода не верен, я этот вердикт не люблю), FL (произошел epic fail — например, чекер выяснил, что решение участника вывело более оптимальный ответ, чем авторское решение). Конечно, при тестировании подготовленных задач не должен появляться FL, но о нем мы расскажем чуть позже.
Конечно, в большинстве задач не требуется «интеллектуальный» чекер, так как условие задачи однозначно определяет вывод участника. Более того, на многих соревнованиях по техническим причинам (TopCoder) или в силу традиций (большое количество ACM-ICPC regionals) это стало правилом. С другой стороны, даже при однозначном выводе могут быть тонкости — на сколько позволять участникам не соблюдать формат. Возможны следующие моменты (и не только они):
- вывод перевода строки или его отсутствие в конце последней строки файла;
- вывод лишних пробелов, особенно в задачах со всякими «Case: 12» или завершающий пробел в конце последовательности чисел;
- вывод вещественных чисел — вообще, отдельная песня, так как надо определяться сколько нужно знаков (ровно столько? не меньше?), да и округлиться 0.34999999 может как угодно.
Все это приводит к заключению, что даже в задачах с однозначным выводом проверка вывода дело тонкое. Обычно, если в условии задачи не написано четко про пробелы, то следует допускать их произвольное расположение в выводе. Лояльность относительно заключительного перевода строки тоже, я думаю, правило хорошего тона. Так как в разных задачах оказывается, что требуется немного разное «точное» сравнение, то и в таких задачах применяют чекеры, просто их не пишут каждый раз, а используют готовые (написанные заранее).
Обычно, чекер компилируется в исполняемый файл, который принимает три (опционально два) аргумента командной строки: входной-файл, файл-вывода, файл-ответа. В англоязычной терминологии это input, output и answer. Возвращает значение чекер обычно через exit-codes выполняемого процесса. За исключением ejudge тестирующие системы обычно используют:
- код возврата 0 для обозначения OK;
- код возврата 1 для обозначения WA;
- код возврата 2 для обозначения PE;
- код возврата 3 для обозначения FL.
Что очень важно хороший чекер выведет в stdout вердикт и его причину в виде короткой фразы на английском языке (иногда для русскоязычных школьных соревнований используется русский язык). Стоит помнить, что вывод должен быть информативен и не очень громоздким. Примеры хороших выводов: «ok n=10, m=13, answer=34», «ok No solution», «wrong answer Expected -1, found 4294967295». Примеры плохих выводов «ok OK», «wrong answer Palevo!».
Чекеры и testlib.h
Писать чекеры — с одной стороны просто, с другой стороны в этом много подводных камней. Что может быть проще написать программу для сравнивания двух целых чисел? Однако вдруг оказывается, что scanf(«%d», &a) (да и многие другие стандартные способы считать целое число во многих языках) при считывании 4294967295 не просигнализирует об ошибке, и будет уверен, что прочел -1. Отделить PE и WA при чтении целого числа тоже отдельная задачка.
По этой причине еще в лохматые 90-е Антоном Сухановым и Романом Елизаровым на был написан testlib для Pascal, который верой и правдой служил на многих NEERC и в модифицированном виде активно используется до сих пор. Иногда возникают проблемы обратной несовместимости версий этой библиотеки или около того (модуль symbols). Заметим, что эта библиотека была переписана Андреем Лопатиным и Николаем Дуровым и другой вариант активно используется на многих контестах СпбГУ и по сей день. На сколько я понимаю, библиотеки эти не совсем совместимы.
Библиотека testlib.h была написана мной в 2005-м году по образу и подобию тестлибов для Pascal. Это позволило упростить переход на нее тем многим, кто уже успел поработать с testlib.pas. Достаточно быстро testlib.h стал использоваться не только на саратовских соревнованиях. Одним из первых широкомасштабных использований стала Всероссийская олимпиада школьников года примерно 2006-го. С тех пор, testlib.h стал де-факто стандартом для написания чекеров на С++ и применяется на совсем разных контестах.
Приведем пример простейшего чекера на testlib.h, который сравнивает answer и output, ожидая в каждом из них по одному 32-х битному целому числу.
#include «testlib.h» int main(int argc, char * argv[])
Я думаю код достаточно понятен. Отмечу, что программе доступны три потока inf, ouf, ans — потоки входных, выходных данных и поток с ответом. Для потоков есть удобные функции чтения, которые позволяют читать разнообразные данные. Ошибки чтения трактуются по разному для разных потоков. Например, если невозможно прочитать число с помощью ouf.readInt(), то будет PE, но если использовался inf.readInt() или ans.readInt() то будет FL. Об этом не надо особенно задумываться при разработке — здесь все вполне логично и естественно. Еще немного примеров (подразумевается чтение из ouf, для inf и ans в случае ошибок будут FL).
- readInt(1, 100, «n») — попытается прочесть целое от 1 до 100, вернет WA (для версий 0.7+, иначе PE) если число не в заданных границах. Текст вывода будет примерно таким: Integer n violates the range [1, 100].
- readInt(1, 100) — тоже самое, но вывод об ошибке немного другой (без указания имени переменной).
- readLong() — читает знаковое 64-х битное число.
- readToken() — читает очередной токен (последовательность непробельных символов), пропускает если надо все whitespaces перед чтением токена.
- readWord() — тоже самое, что и readToken().
- readWord(«[a-z]») — читает токен и удостоверяется, что это последовательность малых латинских букв длины от 1 до 100, вернет WA (для версий 0.7+, иначе PE) если токен не соответствует паттерну.
- seekEof() — пропускает все whitespaces и возвращает true если больше ничего нет в потоке.
- readLine() — читает текущую строку до конца.
Это далеко не все возможности, следует посмотреть testlib.h (строки около 950) чтобы ознакомиться со списком всех возможностей.
Задачи с сертификатом, чекеры
Особо следует отметить такие задачи, в которых требуется сертификат. Так обычно называют вывод не только значения оптимального ответа (например длины наидлиннейшей возрастающей подпоследовательности), но и самой подпоследовательности (например, в виде индексов). Для таких задач существует определенный паттерн написания чекера. Основная часть чекера должна выглядеть как-то так:
n = inf.readInt(); int ja = readAnswer(ans, _fail, _fail); int pa = readAnswer(ouf, _wa, _pe); if (ja < pa) quitf(_wa, "Jury has better answer: %d < %d", ja, pa); if (ja >pa) quitf(_fail, "Participant has better answer: %d < %d", pa, ja); quitf(_ok, "n=%d, m=%d, result=%d", n, m, ja);
Здесь функция readAnswer читает ответ (вывод) из заданного потока, удостоверяется в его корректности и возвращает значение целевой функции оптимизации. Второй и третий параметры функции нужны для того, чтобы использовать их в функции quitf(), это обеспечит FL на ошибках потока ответа и WA/PE на ошибках потока вывода.
Как написать чекер
Приведу список шагов по написанию чекера.
- Если у вас нет неоднозначности в выводе в задаче, то используйте один из стандартных чекеров. Не бойтесь быть слишком лояльными — пусть лучше ваш чекер игнорирует какие-нибудь лишние пробелы, чем будет слишком строг и испортит участникам контест.
- Если в задаче предполагается вывод сертификата, то пишите чекер в соответствии с паттерном в предыдущем разделе. Всегда стоит рассмотреть возможность изменения задачи, чтобы она требовала вывод сертификата. Обычно это делает задачу чуть более программистской, что неплохо.
- Когда пишите чекер, то учтите, что он будет компилироваться на произвольной платформе. В частности, не используйте %I64d/%lld. В testlib.h есть функция vtos(value), которая возвращает строковое представление аргумента value.
- Старайтесь писать максимально надежно. Есть вероятность переполнения — пишите все в long long, и так далее.
- Старайтесь писать все просто и прямо. Не используйте хитрый и неочевидный код.
- Перепрочтите условие задачи и обратите внимание на то, что вы проверяете все требования, изложенные в задаче.
- Будьте аккуратны с WA/PE. Например, если в задаче требуют вывести число или "No solution", то вывод "No solution", не должен приводить к PE.
- Убедиться, что при любом выводе участника чекер не выведет сверхдлинный комментарий. Например, выводя строки их лучше оборачивать в __testlib_part(s). Стандартные чекеры делают именно так, можно почитать их код для уточнения деталей.
- Тщательно потестируйте ваш чекер на предмет его адекватной работы в каждом из возможных вариантов исхода.
Пожалуй все. Пишите в комментариях замечания и предложения. Наверняка, я что-то забыл/упустил.
MikeMirzayanov
P.S. Немного ссылок:
- Официальный сайт testlib.h
- Issue (bug) tracker для testlib.h
- testlib.pas by SPb IFMO CTD Development Team

testlib, подготовка задач, чекеры
