API Определение исходного оператора на Python: одиночные и множественные запросы с помощью requests
Вызывайте API определения оператора из Python с помощью библиотеки requests: одиночные и множественные запросы, упорядоченные результаты и проверка баланса.

Руководство по Python для выполнения одиночных и множественных запросов к API Определение исходного оператора с помощью библиотеки requests, включая обработку ошибок и сопоставление упорядоченных результатов со строками данных.
Для вызова API Определение исходного оператора на Python используйте библиотеку requests для отправки POST-запроса с номером в формате E.164 на адрес /api/v1/check (для получения одного результата) или списка до 100 номеров на адрес /api/v1/batch-check (для получения упорядоченного набора результатов). Передавайте ключ API в заголовке X-API-Key с доверенного сервера, устанавливайте тайм-аут, проверяйте код ответа перед чтением данных и сопоставляйте множественные результаты с исходными строками по позиции и идентификатору. Возвращаемый оператор — это оператор, которому номер был выделен изначально, а не текущая сеть.
Настройка сессии requests для определения оператора
Библиотека requests позволяет выполнять HTTP-запросы лаконично, а объект сессии дает возможность использовать общие заголовки и соединение для всех вызовов. Установите её с помощью pip install requests и храните ключ вне исходного кода, считывая его из переменной окружения.
import os
import requests
BASE_URL = "https://carrierlookup.online"
session = requests.Session()
session.headers.update({
"X-API-Key": os.environ["CARRIERLOOKUP_API_KEY"],
"Accept": "application/json",
})
С самого начала стоит выработать три полезные привычки:
- Выполняйте этот код только на доверенном сервере, рабочем процессе или в блокноте, который вы контролируете. Никогда не передавайте ключ в браузере или мобильном приложении.
- Всегда указывайте
timeoutдля каждого вызова. Без него requests может ожидать ответа бесконечно. - Приводите номера к формату E.164 перед отправкой: знак «плюс», код страны и номер абонента без пробелов и разделителей.
Небольшая вспомогательная функция, удаляющая разделители и добавляющая знак «плюс», избавит от необходимости повторять очистку и предотвратит ошибки форматирования в результатах. Отклоненный формат — это проблема форматирования, а не ответ оператора, поэтому обрабатывайте его до отправки запроса.
Отправка одиночного запроса на /api/v1/check
Одиночный запрос в реальном времени выполняется через POST /api/v1/check. Он принимает один номер в формате E.164 и возвращает ответ в том же запросе. Передавайте номер в теле JSON, как описано в документации API.
def check_one(number: str) -> dict | None:
resp = session.post(
f"{BASE_URL}/api/v1/check",
json=build_single_payload(number), # структура тела: см. документацию API
timeout=65,
)
resp.raise_for_status()
body = resp.json()
if body.get("code") != 0:
print("не завершено:", body.get("msg"))
return None
return body["data"]
Тело ответа содержит code, msg и плоский объект data. code, равный нулю, означает, что проверка завершена успешно. Данные содержат исходного оператора, базового оператора, тип номера, код страны, регион и город. Любое из необязательных значений может быть пустым, и завершенный результат, в котором все значения оператора пусты, по-прежнему является нормальным результатом. Сохраняйте пустые значения как «недоступно», а не как доказательство отсутствия оператора у номера.
Ненулевой code означает, что проверка не была завершена, например, если ответ не удалось определить. Не превращайте этот случай в пустой успешный результат. За неудачные или неопределенные проверки плата не взимается, поэтому повторная попытка с небольшой задержкой вполне уместна. В публичной документации указаны предельные значения тайм-аута для запросов в реальном времени, поэтому поддерживайте тайм-аут клиента на уровне или выше указанного предела для одиночных запросов.
Отправка множественного запроса и сопоставление результатов со строками
Если у вас есть небольшая партия, POST /api/v1/batch-check принимает от 1 до 100 номеров в формате E.164 и возвращает упорядоченный синхронный результат. Номера могут быть из разных стран. Ответ содержит сводку о количестве элементов, количестве успешных и неудачных проверок, а затем список результатов для каждого введенного номера в исходном порядке.
def check_many(numbers: list[str]) -> list[dict]:
resp = session.post(
f"{BASE_URL}/api/v1/batch-check",
json=build_multi_payload(numbers), # структура тела: см. документацию API
timeout=310,
)
resp.raise_for_status()
body = resp.json()
if body.get("code") != 0:
raise RuntimeError(body.get("msg"))
return body["data"]["results"]
Чтобы привязать результаты к вашим строкам, объедините входной список с результирующим списком и убедитесь, что идентификатор каждого элемента совпадает с номером, который вы отправили. Эта вторая проверка защищает от скрытого смещения, если список был изменен между формированием и отправкой запроса.
Каждый элемент также содержит флаг exists. Если он равен false, значит, для элемента нет нормального результата. Это не то же самое, что недействительный или отключенный номер, поэтому сохраняйте его как «нет результата» и позже решите, стоит ли повторить попытку или оставить как есть. Множественный запрос, время ожидания которого истекло, считается полностью неудачным без частичных результатов, и полная сумма возвращается, поэтому безопасным ответом будет повторная отправка того же фрагмента.
Одновременно выполняется только один множественный запрос на аккаунт, поэтому цикл, обрабатывающий фрагменты, должен дождаться завершения каждого вызова перед отправкой следующего.
Разбиение на фрагменты, повторные попытки и проверка баланса
Реальные списки длиннее 100 номеров, поэтому разбивайте их на фрагменты и обрабатывайте каждый по очереди.
def chunks(items, size=100):
for i in range(0, len(items), size):
yield items[i:i + size]
rows = []
for part in chunks(clean_numbers):
rows.extend(check_many(part))
Несколько практических правил помогут сделать этот цикл надежным:
- Сначала удалите дубликаты из очищенного списка, чтобы каждый номер проверялся один раз.
- Обрабатывайте
requests.exceptions.TimeoutиConnectionErrorотдельно от ошибок API и повторяйте попытку ограниченное количество раз с паузой. - Поддерживайте низкий уровень параллелизма. В публичной документации описано небольшое количество общих слотов для запросов в реальном времени и не публикуется фиксированный лимит в минуту, поэтому избегайте запуска большого количества параллельных потоков.
- Записывайте каждый завершенный фрагмент на диск или в базу данных сразу после получения, чтобы сбой не привел к потере выполненной работы.
Перед запуском большого объема проверок вызовите GET /api/v1/balance. Это позволит считать баланс аккаунта без списания средств и даст скрипту возможность остановиться заранее с понятным сообщением, вместо того чтобы завершиться с ошибкой на полпути. И сервисы реального времени, и файловые сервисы используют один баланс и тарифицируются за каждый завершенный номер.
Для списков, значительно превышающих несколько фрагментов, асинхронная файловая задача подходит лучше, чем длинный цикл синхронных вызовов. Файловая задача — это отдельный рабочий процесс со своей собственной конечной точкой, а не просто увеличенная версия множественного запроса.
Ответственная интерпретация результатов
Как только данные попали в таблицу pandas или базу данных, основной риск заключается в их неверной интерпретации. Оператор — это тот, которому диапазон номеров был выделен изначально. После переноса номера (MNP) человек может пользоваться услугами другого оператора. Регион и город описывают географию выделения номера, а не то, где сейчас находится человек или телефон. Тип номера указывает на вид диапазона, а не на то, активна ли линия.
К полезным способам использования относятся группировка записей для тестирования маршрутизации провайдеров, пометка необычных типов номеров для проверки и добавление контекстных столбцов в CRM. К нежелательным способам использования относятся попытки определить, доступен ли номер, предположения о том, кто им владеет, или выводы о наличии согласия.
Простая схема сохраняет ясность значений: исходный оператор, базовый оператор, тип номера, код страны, регион, город, статус проверки и время проверки. Столбец статуса разделяет завершенные, пустые и неудачные результаты, чтобы последующие отчеты не смешивали их.
Часто задаваемые вопросы
Какая библиотека Python лучше всего подходит для вызовов API определения оператора?
Библиотеки requests достаточно как для одиночной, так и для множественной конечной точки. Используйте сессию для передачи заголовка с ключом API, всегда устанавливайте тайм-аут и вызывайте raise_for_status вместе с проверкой кода ответа. Для большого количества одновременных заданий держите пул небольшим, так как слоты реального времени являются общими для всего аккаунта.
Как команды могут сопоставить множественные результаты с входными строками?
Результаты возвращаются в порядке ввода, и каждый элемент повторяет идентификатор, который был отправлен. Объедините входной список с результатами, а затем проверьте, что каждый идентификатор соответствует своей строке перед записью данных. Элементы, для которых флаг exists равен false, следует сохранять как «нет нормального результата», а не как недействительные номера.
Где должен храниться ключ API в проекте на Python?
Храните его в переменной окружения или менеджере секретов на доверенном сервере и считывайте при запуске. Не добавляйте его в систему контроля версий и не передавайте из кода браузера или мобильного приложения. Если он попал в лог или репозиторий, смените его и проверьте недавнюю активность.
Узнайте больше
Выберите информацию о продукте, которая соответствует следующему шагу в вашем рабочем процессе.