From bde38cdce750e9f6d15502ba0a300195b60c4aef Mon Sep 17 00:00:00 2001 From: bot-backend Date: Tue, 8 Sep 2026 22:54:44 +0300 Subject: [PATCH] =?UTF-8?q?fix(msk-collector):=20--resume=20=D0=B1=D0=B5?= =?UTF-8?q?=D1=80=D1=91=D1=82=20base=5Furl=20=D0=B8=D0=B7=20=D1=81=D0=BE?= =?UTF-8?q?=D1=85=D1=80=D0=B0=D0=BD=D1=91=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=BB=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Коридоры считаются под конкретный URL выдачи. При --resume код брал свежий args.base_url, поэтому запуск без повтора --base-url молча качал другую выдачу под тем же batch_id. Теперь URL из плана, расхождение с аргументом — явная ошибка вместо тихого выбора одного из двух. --- .../scripts/local-avito-msk/collect.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tradein-mvp/scripts/local-avito-msk/collect.py b/tradein-mvp/scripts/local-avito-msk/collect.py index 2432cc86..8df91f48 100644 --- a/tradein-mvp/scripts/local-avito-msk/collect.py +++ b/tradein-mvp/scripts/local-avito-msk/collect.py @@ -527,13 +527,24 @@ async def collect(args: argparse.Namespace) -> int: print(f"Resume по {plan_path}: коридоров {len(plan.corridors)}, " f"готово {done}", flush=True) + # Resume: URL берём из сохранённого плана, а не из CLI — коридоры посчитаны + # именно под него. Расхождение = молчаливая заливка чужой выдачи под тем же + # batch_id, поэтому это ошибка, а не тихий приоритет одного из двух. + if plan is not None and plan.base_url != args.base_url: + raise SystemExit( + "--resume: план построен для другого URL." + f" В плане {plan.base_url}, в аргументах {args.base_url}." + " Убери --base-url (возьмётся из плана) либо начни новый batch_id." + ) + base_url = plan.base_url if plan is not None else args.base_url + page_budget = None if args.full else args.measure mode = "FULL" if args.full else f"MEASURE<={page_budget}" print(f"Режим: {mode}; batch_id={args.batch_id}; delay={args.delay}s; " f"target={args.target_count}; dry_run={args.dry_run}", flush=True) sink = Sink( - batch_id=args.batch_id, started_at=started_at, query=args.base_url, + batch_id=args.batch_id, started_at=started_at, query=base_url, batch_size=args.batch_size, dry_run=args.dry_run, csv_path=csv_path, ssh_host=args.ssh_host, container=args.container, db_user=args.db_user, db_name=args.db_name, @@ -548,9 +559,9 @@ async def collect(args: argparse.Namespace) -> int: try: if plan is None: print("Строю план коридоров...", flush=True) - corridors = await build_plan(loader, scraper, args.base_url, + corridors = await build_plan(loader, scraper, base_url, args.target_count, cache) - plan = Plan(base_url=args.base_url, target=args.target_count, + plan = Plan(base_url=base_url, target=args.target_count, batch_id=args.batch_id, corridors=corridors, created_at=started_at) plan.save(plan_path) @@ -568,7 +579,7 @@ async def collect(args: argparse.Namespace) -> int: if page == 1 and key in cache: lots = cache.pop(key) # страница 1 уже скачана при планировании else: - url = build_url(args.base_url, page, corridor.lo, corridor.hi) + url = build_url(base_url, page, corridor.lo, corridor.hi) html, _ = await loader.fetch(url) _, lots = parse_page(scraper, html, url) for lot in lots: