fix(color_extractor): CSS .logo 패턴 우선순위 + lang/flag noise 필터 강화
문제: JK 성형외과 (jkplastic.com) 처럼 <h1 class="logo"><a>JK PLASTIC</a></h1>
형태로 logo 텍스트만 있고 진짜 이미지는 외부 CSS의 .logo { background-image: url(...) }
로 들어가는 사이트에서, generic <header> 첫 img 패턴이 한국어 깃발(lang-kor.png)을
먼저 잡아 잘못된 로고가 박혔음.
수정:
- find_logo_url_in_html 흐름 재정렬:
1) class/id/alt/src 명시 + 부모 class="logo" + 중첩 img (specific)
2) **외부 CSS 의 .logo background-image** ← generic 보다 앞으로 (class-based 라
더 specific)
3) <header>/<nav> 첫 img (가장 generic, 잘못 잡힐 위험)
- noise 필터 강화: lang-kor / lang-eng / flag / country / icon- / btn- / arrow /
prev / next / search 같이 logo 아닌 게 명백한 src 는 모든 단계에서 skip
검증: JK 는 lang-kor.png → logo-color.png 로 정확히 잡힘.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
channel-brand
parent
dca0c78860
commit
fa32109658
|
|
@ -84,22 +84,47 @@ LOGO_CSS_PATTERN = re.compile(
|
||||||
|
|
||||||
|
|
||||||
def find_logo_url_in_html(html: str, base_url: str, css_texts: list[str] | None = None) -> str | None:
|
def find_logo_url_in_html(html: str, base_url: str, css_texts: list[str] | None = None) -> str | None:
|
||||||
"""HTML에서 logo URL 찾기. class/id/alt → 부모 + 중첩 img → background-image → src에 logo → header/nav → og:image 순."""
|
"""HTML에서 logo URL 찾기. 우선순위:
|
||||||
for pat in LOGO_IMG_PATTERNS:
|
1) 패턴 1~8 (class/id/alt/src에 'logo' 명시된 img — 가장 specific)
|
||||||
|
2) 외부 CSS의 .logo background-image (class-based, 더 specific)
|
||||||
|
3) 패턴 9~10 (<header>/<nav> 안 첫 img — 가장 generic, 잘못 잡힐 위험 큼)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _is_noise(src: str) -> bool:
|
||||||
|
"""logo로 잘못 잡힐 가능성 높은 URL 패턴 — lang/flag/icon/arrow/spacer 등."""
|
||||||
|
if not src or src.startswith("data:"):
|
||||||
|
return True
|
||||||
|
if re.search(r"(blank|spacer|pixel|transparent|1x1)\b", src, re.IGNORECASE):
|
||||||
|
return True
|
||||||
|
# 헤더 첫 img가 lang flag / 검색 아이콘 / 네비 화살표인 경우 (JK plastic 한국어 깃발이 잡히던 케이스)
|
||||||
|
if re.search(r"(lang[-_]?(kor|eng|chn|jpn|rus|jp|en|ko|cn|ar|in)|flag|country|icon-|btn-|arrow|prev|next|search)\b", src, re.IGNORECASE):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 1) class/id/alt/src/inline-bg/src-with-logo 패턴 (1~8)
|
||||||
|
for pat in LOGO_IMG_PATTERNS[:8]:
|
||||||
for m in pat.finditer(html):
|
for m in pat.finditer(html):
|
||||||
src = m.group(1)
|
src = m.group(1)
|
||||||
if not src or src.startswith("data:"):
|
if _is_noise(src):
|
||||||
continue
|
|
||||||
if re.search(r"(blank|spacer|pixel|transparent|1x1)\b", src, re.IGNORECASE):
|
|
||||||
continue
|
continue
|
||||||
return urljoin(base_url, src)
|
return urljoin(base_url, src)
|
||||||
# 외부 CSS에서 .logo background-image 추출
|
|
||||||
|
# 2) 외부 CSS의 .logo { background-image } — class-based 이므로 generic 패턴보다 우선
|
||||||
for css in (css_texts or []):
|
for css in (css_texts or []):
|
||||||
m = LOGO_CSS_PATTERN.search(css)
|
m = LOGO_CSS_PATTERN.search(css)
|
||||||
if m:
|
if m:
|
||||||
src = m.group(1)
|
src = m.group(1)
|
||||||
if src and not src.startswith("data:"):
|
if not _is_noise(src):
|
||||||
return urljoin(base_url, src)
|
return urljoin(base_url, src)
|
||||||
|
|
||||||
|
# 3) header/nav 첫 img — 가장 generic, lang flag 등 noise 필터 강화 적용
|
||||||
|
for pat in LOGO_IMG_PATTERNS[8:]:
|
||||||
|
for m in pat.finditer(html):
|
||||||
|
src = m.group(1)
|
||||||
|
if _is_noise(src):
|
||||||
|
continue
|
||||||
|
return urljoin(base_url, src)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue