Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумСбор данных

Дубликаты в каталоге: как ловить при сборе

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
15 июля, 14:42первое сообщение

Собрал каталог поставщика, ожидал тысяч сорок позиций, получил шестьдесят три. Полез смотреть и понял, что треть выгрузки это одни и те же товары, приехавшие разными путями.

Причины нашёл три: - товар лежит сразу в нескольких разделах, адреса разные; - к адресу цепляются метки перехода, каждая даёт новую строку; - у части позиций есть версия для печати и обычная, содержимое одинаковое.

Ловить дубликаты после сбора неприятно: половина ночи потрачена на повторные запросы. Хочу отсекать их прямо в очереди. Чем считать, что это один товар?

Юля Ким
Юля Ким
Знаток
сообщений 1240
с мая
22 декабря, 17:59#2

Считать надо не по адресу. Адрес это способ доехать, а товар определяется артикулом.

Первый заход самый дешёвый: приводите адреса к общему виду перед постановкой в очередь. Метки перехода, якоря, слеш на конце, порядок параметров, а заодно схема и хост: http и https на один и тот же путь дают две строки, и обход честно ходит дважды.

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
1 мая, 08:16#3
Юля Ким: приводите адреса к общему виду перед постановкой в очередь

Так и сделал, отсеклось процентов двенадцать. Остальное это тот же товар под разными путями, там нормализация бессильна.

nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
8 октября, 11:33#4

Дальше работает отпечаток содержимого. Порядок такой, от дешёвого к дорогому.

Артикул производителя. Если он есть на странице, всё остальное лишнее: два адреса с одинаковым артикулом это один товар. Кладите артикул в отдельную таблицу с уникальным ключом, вставка второй раз просто не проходит.

Пара из названия и веса или объёма. Работает, когда артикула нет. Название приводите к нижнему регистру, выкидывайте лишние пробелы и знаки, и только потом сравнивайте.

Отпечаток по содержимому. Берёте текст карточки без меню и подвала, считаете хеш, сравниваете. Ловит версию для печати и зеркала разделов, потому что там текст совпадает буквально.

import hashlib, re

def otpechatok(nazvanie, ves, opisanie): n = re.sub(r'[^\w\s]', ' ', nazvanie.lower()) n = ' '.join(n.split()) stroka = f'{n}|{ves}|{len(opisanie)}' return hashlib.blake2b(stroka.encode(), digest_size=16).hexdigest() ```

Длину описания добавляю специально: два разных товара с похожим названием почти никогда не совпадают ещё и по ней.

если не воспроизводится, значит не понял
Егор Пастухов
Егор Пастухов
Новичок
сообщений 78
с июл, второй сезон
15 марта, 14:50#5

а как понять, что это дубль, если такой же товар бывает и у другого поставщика?

Максим Юрьев
Максим Юрьев
Знаток
сообщений 1720
с апр
22 августа, 17:07#6

По источнику. Отпечаток считается внутри одного поставщика, между поставщиками сравнение отдельное и с другими правилами.

У меня в таблице ключ составной: код поставщика плюс отпечаток. Один и тот же холодильник у двух поставщиков это две строки, и правильно, у них разные условия. А тот же холодильник дважды у одного поставщика это дубль.

Юля Ким
Юля Ким
Знаток
сообщений 1240
с мая
1 января, 08:24#7

Хорошее уточнение. Добавлю про очередь: проверку на дубль надо делать при постановке задачи, до запроса. Иначе экономии по времени никакой.

У меня очередь принимает задачу через вставку с игнорированием повтора, и вся защита сводится к одному уникальному индексу на нормализованном адресе.

CREATE UNIQUE INDEX ux_zadacha ON ochered (postavshchik, adres_norm);
INSERT INTO ochered (postavshchik, adres_norm, adres) VALUES (?, ?, ?)
ON CONFLICT DO NOTHING;
byteflow
byteflow
Новичок
сообщений 225
с фев, второй сезон
8 июня, 11:41#8

Отпечаток по содержимому при постановке в очередь не посчитать, страницы ещё нет. Поэтому у меня два рубежа: адрес отсекается на входе, содержимое после разбора, перед записью в каталог.

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
15 ноября, 14:58#9

Собрал по вашим советам три рубежа: нормализация адреса, уникальный ключ по артикулу, отпечаток по тексту для тех, у кого артикула нет.

Ночной прогон дал сорок одну тысячу позиций против шестидесяти трёх. Запросов ушло на треть меньше, время сократилось с семи часов до четырёх с половиной.

Остался один странный хвост: около двухсот карточек ловятся как дубли, хотя на глаз товары разные. Пошёл разбираться.

nullbyte
nullbyte
Ветеран
сообщений 2680
с апр
22 апреля, 17:15#10

Посмотрите на них с другого выхода в сеть. Знакомый почерк: сайт отдаёт заглушку с одинаковым текстом, когда решает, что запросы идут слишком часто, и все такие заглушки конечно совпадают по отпечатку.

если не воспроизводится, значит не понял
Максим Юрьев
Максим Юрьев
Знаток
сообщений 1720
с апр
1 сентября, 08:32#11

Согласен, симптом ровно тот. Проверяется в лоб: возьмите десяток спорных адресов и запросите их спокойно, с паузой, через другой выход. Я под такие перепроверки держу пакет приватных адресов под задачи парсинга, тест включается за пять минут и сразу видно, приходит настоящая карточка или заглушка.

три рубежа против дублей
три рубежа против дублей
grepwalker
grepwalker
Знаток
сообщений 1330
с мая
8 февраля, 11:49#12

Так и оказалось: под конец прогона сайт начинал отдавать одну и ту же короткую страницу. Через спокойный запрос все двести пришли нормальными карточками.

Убрал жадность, поставил паузу с разбросом, хвост исчез. Итог: сорок одна тысяча позиций, дублей ноль, заглушек ноль.