df83fa836c
Шаг 1 «Конкурентное поле» — чекпоинт: - Финальный проход «Найти и объединить дубли» на поле и предложениях; клиент решает по каждой группе, ничего не склеиваем молча. - Тихая склейка только по сайту и коду справочника; телефон и людный номер у более чем 4 фирм — на решение клиента. - Колонка phones jsonb; телефон-дубли видны уже на «Предложениях». - Sonar даёт только имя и тип, сайт всегда через EXA; вскрываем все карточки без гейта «есть сайт». - Яндекс-карточки через локальный Playwright параллельно; рубрика из заголовка идёт в описание. - Фикс рекламных номеров: 2ГИС-парсер разбирает телефоны пообъектно и выкидывает рекламные кнопки с platforms/caption чужих фирм. Тесты: автоподбор 224/224 unit, 105/105 feature; фронт-спеки зелёные. Времянки app/scripts/diag-*/probe-* в гит не входят. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
2.1 KiB
PHP
58 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\Autopodbor\Agent\Fetch\BatchPageFetcher;
|
|
use App\Services\Autopodbor\Agent\Fetch\RoutingBatchFetcher;
|
|
|
|
// Роутер загрузки: по подстроке URL направляет к нужному фетчеру. Яндекс-карточки → локальный
|
|
// Playwright (надёжно достаёт сайт), 2ГИС и прочее → xfetch. Каждый фетчер тегает html, проверяем маршрут.
|
|
|
|
function tagFetcher(string $tag): BatchPageFetcher
|
|
{
|
|
return new class($tag) implements BatchPageFetcher
|
|
{
|
|
public function __construct(private string $tag) {}
|
|
|
|
public function html(string $url): string
|
|
{
|
|
return $this->tag.':'.$url;
|
|
}
|
|
|
|
public function htmlBatch(array $urls): array
|
|
{
|
|
$out = [];
|
|
foreach ($urls as $u) {
|
|
$out[$u] = $this->tag.':'.$u;
|
|
}
|
|
|
|
return $out;
|
|
}
|
|
};
|
|
}
|
|
|
|
it('htmlBatch: яндекс идёт в яндекс-фетчер, остальное — в дефолтный', function () {
|
|
$r = new RoutingBatchFetcher(tagFetcher('X'), ['yandex' => tagFetcher('PW')]);
|
|
|
|
$out = $r->htmlBatch([
|
|
'https://yandex.ru/maps/org/a/1',
|
|
'https://2gis.ru/krasnoyarsk/firm/2',
|
|
]);
|
|
|
|
expect($out['https://yandex.ru/maps/org/a/1'])->toBe('PW:https://yandex.ru/maps/org/a/1')
|
|
->and($out['https://2gis.ru/krasnoyarsk/firm/2'])->toBe('X:https://2gis.ru/krasnoyarsk/firm/2');
|
|
});
|
|
|
|
it('html(): одиночная загрузка тоже маршрутизируется', function () {
|
|
$r = new RoutingBatchFetcher(tagFetcher('X'), ['yandex' => tagFetcher('PW')]);
|
|
|
|
expect($r->html('https://yandex.ru/x'))->toBe('PW:https://yandex.ru/x')
|
|
->and($r->html('https://2gis.ru/y'))->toBe('X:https://2gis.ru/y');
|
|
});
|
|
|
|
it('без маршрутов всё идёт в дефолтный', function () {
|
|
$r = new RoutingBatchFetcher(tagFetcher('X'));
|
|
|
|
expect($r->htmlBatch(['https://yandex.ru/z']))->toBe(['https://yandex.ru/z' => 'X:https://yandex.ru/z']);
|
|
});
|