Бюджет QA: считаем попытки, а не IP
Проверку каталога удобно описывать количеством страниц, но расход создают попытки: успешные запросы, повторения, ресурсы страницы и незавершённые ответы. Число IP само по себе не говорит, сколько данных потребуется. Ниже — небольшой CSV-план, который проверяется локально до запуска задачи. Он помогает найти ошибку арифметики, а не обещает будущий счёт.
Раскрытие связи: материал подготовлен Portproof, где продаются прокси и другие продукты для подключения, с помощью ИИ и последующей редакционной проверкой. Все значения, названия сценариев и результаты расчёта ниже учебные. Клиентская сеть, живой прокси и платная операция не использовались.
Сначала определите, что именно считаете
Одна страница в браузере может загрузить изображения, шрифты и фоновые запросы. Один HTTP-клиент, напротив, может получить только небольшой ответ. Поэтому нельзя взять количество страниц и умножить его на универсальный «расход сайта». Сначала выделите разрешённый сценарий и единицу собственного наблюдения.
Для плана нам понадобятся число случаев, максимальное число попыток на случай и два размера: отправленные и полученные байты. Размеры должны относиться к одной понятной точке измерения. Не смешивайте счётчик распакованного тела, размер загруженного файла и сетевой счётчик. Даже корректный итог этой таблицы не заменяет правила учёта трафика услуги.
Если сценарий ещё не измерен, запишите предположение как предположение. После небольшого разрешённого запуска замените его собственным наблюдением, сохранив метод и дату. Руководство по объёму прокси-трафика объясняет границу между образцом и будущей нагрузкой.
CSV для трёх разных видов работы
Скопируйте этот учебный файл. bounded_retry — отдельная группа из пяти случаев, для которых в плане заложено не более двух попыток. Это не дополнительное повторение всех предыдущих строк.
scenario,cases,attempts_per_case,request_bytes,response_bytes
catalog_baseline,20,1,800,24000
image_variant,10,1,800,180000
bounded_retry,5,2,800,24000
В таблице 35 случаев и 40 попыток. Если повтор понадобится только двум случаям из пяти, фактическое число попыток будет меньше заложенного максимума. Если приложение бесконечно повторяет отказ, эта таблица его не остановит: лимит нужно реализовать в самой задаче.
Не храните здесь пароли, полные URL с авторизацией, ответы покупателей или платёжные данные. Для бюджетного плана достаточно обозначения сценария и агрегатов. Рабочую таблицу с чувствительными наблюдениями не следует автоматически публиковать рядом с задачей в общем трекере.
Проверка без запроса в сеть
Сценарий использует стандартную библиотеку: csv читает строки, а Decimal сохраняет десятичную арифметику в заданных пределах. Сохраните код как budget.py и выполните python3 budget.py. Никакой пакет устанавливать не требуется.
Он отвергает пропущенные столбцы, повторённые имена, отрицательные или дробные счётчики и заведомо большие задания. Эти пределы принадлежат учебной утилите, а не тарифу Portproof. Входные байты складываются до перевода в десятичные ГБ; 1 ГБ в этой арифметике равен 1 000 000 000 байт.
import csv
import io
import json
from decimal import Decimal
CSV = """scenario,cases,attempts_per_case,request_bytes,response_bytes
catalog_baseline,20,1,800,24000
image_variant,10,1,800,180000
bounded_retry,5,2,800,24000
"""
def estimate(text, headroom_percent=20, repeats=100):
fields = ["scenario", "cases", "attempts_per_case", "request_bytes", "response_bytes"]
reader = csv.DictReader(io.StringIO(text))
if reader.fieldnames != fields:
raise ValueError("Unexpected columns")
if type(headroom_percent) is not int or not 0 <= headroom_percent <= 300:
raise ValueError("Invalid headroom")
if type(repeats) is not int or not 1 <= repeats <= 10_000:
raise ValueError("Invalid repeat count")
seen = set()
total = attempts = 0
for row in reader:
name = row["scenario"]
if not name or name in seen or None in row:
raise ValueError("Missing or duplicate scenario")
seen.add(name)
if len(seen) > 100:
raise ValueError("Worksheet has too many rows")
values = []
for field, limit in zip(fields[1:], [10_000, 1_000, 10**9, 10**9]):
raw = row[field]
if raw is None or not raw.isascii() or not raw.isdecimal():
raise ValueError("Counts must be nonnegative ASCII integers")
value = int(raw)
if value > limit:
raise ValueError("Count outside worksheet limit")
values.append(value)
cases, per_case, sent, received = values
if not cases or not per_case:
raise ValueError("Cases and attempts must be positive")
attempts += cases * per_case
total += cases * per_case * (sent + received)
if not seen:
raise ValueError("Empty worksheet")
reserved = Decimal(total) * (100 + headroom_percent) / 100
return {
"fictional": True,
"attempts": attempts,
"input_bytes_per_run": total,
"reserved_decimal_GB_per_run": str(reserved / 1_000_000_000),
"repeated_reserved_decimal_GB": str(reserved * repeats / 1_000_000_000),
"repeats": repeats,
}
if __name__ == "__main__":
print(json.dumps(estimate(CSV), indent=2))
Что получилось в учебном примере
Исходная сумма равна 2 552 000 байт за один запуск. Выбранный нами запас 20% даёт 0,0030624 десятичного ГБ, а 100 таких запусков — 0,30624 ГБ. Это вычисление для вымышленных размеров, не рекомендация покупать именно такой объём. Значение fictional: true оставлено в результате намеренно.
Запас 20% выбран автором для примера. Он не измерен на сети и не гарантирует достаточности: изменение страницы, сжатия, кэша или поведения повторов может изменить расход сильнее. Число запусков 100 тоже не взято из аналитики клиента. Перед рабочим расчётом замените оба допущения и перепроверьте результат.
Такой файл полезнее округлённого обещания «хватит одного ГБ»: можно показать, какая строка увеличила план. Например, рост изображений влияет на image_variant, а увеличение повторов — на bounded_retry. Не скрывайте оба изменения внутри одного среднего размера ответа.
Назначьте остановку отдельно от бюджета
У задачи должны быть понятные основания остановиться: отказ авторизации, ограничение принимающего сервиса, неожиданное содержимое, исчерпание разрешённого числа попыток или внутреннего бюджета. Успешное чтение таблицы не даёт разрешения на запросы. Повторы должны учитывать правила владельца ресурса и состояние операции; не превращайте сетевую проверку в повторную отправку заказа.
Для проверки цен на разрешённых ресурсах сохраняйте статус и качество ответа вместе с расходом. Пустая выдача или страница ошибки не становятся полезными данными из-за небольшого размера. Ошибочные попытки также нужно учитывать в своей модели работы.
Выбор продукта — другой вопрос
Когда объём собственного сценария понятен, сравните единицы покупки. Трафик за ГБ и аренда мобильного устройства на срок решают разные задачи. Сравнение трафика и аренды не следует заменять числом строк CSV: оно не устанавливает нужный режим доступа или ограничения выбранного предложения.
Текущие тарифы и условия заказа остаются источником цены. Таблица не содержит курса валют, скидки, срока услуги или обещания постоянного IP. Кабинет и оформление заказа Portproof доступны на английском. Этой утилитой можно пользоваться независимо от покупки.
Проверка автора относится только к локальной арифметике и обработке ошибочного входа. Для своего окружения сначала выполните небольшой разрешённый образец, затем сопоставьте измерения с правилами услуги. Ни эта публикация, ни резерв в процентах не подтверждают будущую скорость, географию или успешный результат другого сайта.
Авторская локальная проверка выполнена 31 октября 2026 года на CPython 3.9.6: для этой утилиты проверены один корректный и пять ошибочных входов, без сетевых операций. Это граница проверки примера, а не рекомендация выбирать данную версию Python для нового проекта.
Comments
Join the discussionNo comments yet. Be the first to comment.