feat(tags): odrzucaj tagi marketingowe zamiast opisujacych tresc
Zgloszenie 778cd5be: "cos za duzo tych tagow, one sa faktycznie na stronie czy to over attribution?". Sprawdzone u zrodla: tytul posta na sxyprn ma dokladnie te 28 hashtagow, wiec to NIE nasza over-atrybucja, tylko uploader wklejajacy ten sam blok do kazdego wideo (stad #France i #french przy amerykanskiej scenie). Statystycznie tego nie da sie odsiac: blok jest inny u kazdego uploadera, a najczestszy tag na sxyprn (Hardcore) ma 47% udzialu, wiec zaden prog nie oddziela spamu od prawdy. Da sie za to wyciac slowa, ktore nigdy nie opisuja tresci. Tylko to robi ta zmiana. Filtr wpiety w resolve_tag, czyli jedno miejsce, przez ktore ida wszystkie tagi z kazdego zrodla, wiec nie wroca przy re-scrape. Retroaktywnie skasowane 137 861 przypisan scen i 247 filmow, 29 tagow. Sprawdzone przed kasowaniem: tylko 270 scen zostaje bez tagow i ZERO userow ma ktorykolwiek z nich na liscie ukrytych. Srednia liczba tagow na scene 7,7 -> 7,3. VACUUM ANALYZE odpalony od razu. Swiadomie zostawione: onlyfans (realny typ tresci, 72 tys. przypisan) oraz 4k/hd/720p (niosa informacje, choc apka ma juz wiarygodny filtr jakosci ze zrodel odtwarzania, wiec to decyzja produktowa, nie sprzatanie smieci). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
a1f604a7a4
commit
38a2724963
2 changed files with 79 additions and 0 deletions
74
app/normalize/tag_stoplist.py
Normal file
74
app/normalize/tag_stoplist.py
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
"""Tagi, ktore nie opisuja tresci, tylko ja reklamuja.
|
||||||
|
|
||||||
|
Skad sie biora: czesc tubow (najmocniej sxyprn) pozwala uploaderowi wpisac dowolne
|
||||||
|
hashtagi w tytul, a uploaderzy wklejaja ten sam blok do kazdego posta. Zgloszenie
|
||||||
|
778cd5be pokazalo scene z 28 tagami, gdzie w tytule u zrodla stalo dokladnie
|
||||||
|
`#Anal #BigDicks ... #France #Hotwife #artporn #french` przy amerykanskiej scenie.
|
||||||
|
|
||||||
|
Wazne rozroznienie: TEGO NIE DA SIE naprawic wykrywaniem "spamu" statystycznie, bo
|
||||||
|
blok jest inny u kazdego uploadera, a najczestszy tag na sxyprn (Hardcore) ma tylko
|
||||||
|
47% udzialu, wiec zaden prog nie oddziela spamu od prawdziwych tagow. Da sie za to
|
||||||
|
usunac slowa, ktore NIGDY nie sa opisem tresci, niezaleznie od zrodla. Tylko to
|
||||||
|
robi ta lista.
|
||||||
|
|
||||||
|
Kryterium wpisu: tag nie zawezaja wyszukiwania, bo pasuje do niemal wszystkiego
|
||||||
|
w katalogu ("porn", "sex", "hot"), albo opisuje sposob dystrybucji, a nie tresc
|
||||||
|
("premium", "exclusive", "leaked", "download").
|
||||||
|
|
||||||
|
Swiadomie NIE na liscie:
|
||||||
|
- `onlyfans` (71 972 przypisan) - to realny typ tresci, ludzie tego szukaja.
|
||||||
|
- `4k`, `hd`, `720p`, `1080p` (ok. 110 tys.) - niosa jakas informacje, choc
|
||||||
|
niepewna. Apka ma osobny, wiarygodny filtr jakosci liczony ze zrodel odtwarzania,
|
||||||
|
wiec te tagi sa zbedne, ale usuniecie ich to decyzja produktowa, nie sprzatanie
|
||||||
|
smieci. Do przegadania osobno.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
#: Porownanie po slugu (lowercase, dywizy), bo ta sama rzecz przychodzi jako
|
||||||
|
#: "Full HD", "full-hd" i "FullHD".
|
||||||
|
JUNK_TAG_SLUGS: frozenset[str] = frozenset(
|
||||||
|
{
|
||||||
|
# pasuje do calego katalogu, wiec nie zawezaja niczego
|
||||||
|
"porn",
|
||||||
|
"porno",
|
||||||
|
"sex",
|
||||||
|
"xxx",
|
||||||
|
"adult",
|
||||||
|
"nude",
|
||||||
|
"nudes",
|
||||||
|
"hot",
|
||||||
|
"sexy",
|
||||||
|
"video",
|
||||||
|
"videos",
|
||||||
|
"movie",
|
||||||
|
"clip",
|
||||||
|
# marketing i sposob dystrybucji, nie tresc
|
||||||
|
"new",
|
||||||
|
"newest",
|
||||||
|
"latest",
|
||||||
|
"top",
|
||||||
|
"best",
|
||||||
|
"popular",
|
||||||
|
"trending",
|
||||||
|
"premium",
|
||||||
|
"exclusive",
|
||||||
|
"free",
|
||||||
|
"leaked",
|
||||||
|
"siterip",
|
||||||
|
"megapack",
|
||||||
|
"highquality",
|
||||||
|
"high-quality",
|
||||||
|
"watch",
|
||||||
|
"watch-online",
|
||||||
|
"download",
|
||||||
|
"stream",
|
||||||
|
"streaming",
|
||||||
|
"online",
|
||||||
|
"full-video",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_junk_tag(slug: str) -> bool:
|
||||||
|
"""True dla tagu, ktorego nie chcemy trzymac w katalogu."""
|
||||||
|
return slug.strip().lower() in JUNK_TAG_SLUGS
|
||||||
|
|
@ -10,6 +10,7 @@ from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.models.tag import Tag
|
from app.models.tag import Tag
|
||||||
from app.normalize.scenes import NormalizedTag
|
from app.normalize.scenes import NormalizedTag
|
||||||
|
from app.normalize.tag_stoplist import is_junk_tag
|
||||||
from app.normalize.text import slugify
|
from app.normalize.text import slugify
|
||||||
|
|
||||||
_ALTKEY_RE = re.compile(r"[^a-z0-9]")
|
_ALTKEY_RE = re.compile(r"[^a-z0-9]")
|
||||||
|
|
@ -83,6 +84,10 @@ def resolve_tag(session: Session, *, norm: NormalizedTag) -> Tag | None:
|
||||||
# the whole ingest batch.
|
# the whole ingest batch.
|
||||||
if len(slug) > 120:
|
if len(slug) > 120:
|
||||||
return None
|
return None
|
||||||
|
# Tagi czysto marketingowe ("porn", "hot", "premium") odrzucamy na wejsciu, zeby
|
||||||
|
# nie wracaly przy kazdym re-scrape. Patrz app/normalize/tag_stoplist.py.
|
||||||
|
if is_junk_tag(slug):
|
||||||
|
return None
|
||||||
slug = _canonical_dup2_slug(session, slug)
|
slug = _canonical_dup2_slug(session, slug)
|
||||||
tag = session.execute(select(Tag).where(Tag.slug == slug)).scalar_one_or_none()
|
tag = session.execute(select(Tag).where(Tag.slug == slug)).scalar_one_or_none()
|
||||||
if tag is not None:
|
if tag is not None:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue