Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crawler

카페24 기반 화장품 쇼핑몰 6곳에서 상품을 수집하고, 상세페이지의 전성분 텍스트를 읽어 8개 타깃 성분(히알루론산, 판테놀, 알로에, 세라마이드, 센텔라, 나이아신아마이드, 비타민C, 징크) 중 어떤 게 포함됐는지 매칭해 백엔드 Product 시드 데이터(JSON)를 만든다.

결과물은 두 파일로 나뉜다.

  • output/products_seed.json — 6개 사이트를 자동 크롤링해서 만든 데이터.
  • output/products_manual.json — 자동 크롤링만으로는 비타민C/알로에/징크 표본이 너무 적어서, 팀원이 직접 찾은 상품을 수동으로 추가한 데이터. 신뢰도 표시를 위해 자동 크롤링 결과와 파일을 분리해뒀다.

대상 브랜드 & 왜 이 6곳인가

원래 후보는 14개 사이트였고, 플랫폼별로 크롤링 난이도가 크게 갈렸다.

  • 카페24 계열product/list.html 같은 공통 URL 패턴을 쓰고 서버 렌더링이라 일반 크롤링(requests + BeautifulSoup)으로 충분히 뚫린다. 파서 하나를 만들면 사이트 간 재사용도 잘 된다.
  • 네이버 스마트스토어/브랜드관 계열(5곳) — JS 렌더링이 심하고 봇 차단이 강해 Selenium 같은 브라우저 자동화가 필요하고, 그마저도 자주 막힌다. 시간 대비 리스크가 커서 이번 크롤러 범위에서 제외했다.
  • 카페24 계열 중에서도 아크로패스는 스킨/토너·앰플/세럼·크림·미스트 카테고리에 해당하는 상품이 거의 없어서(마이크로니들 패치가 메인) 제외했다.

그래서 남은 카페24 계열 6곳을 대상으로 정했다.

사이트 키 브랜드 운영사
paparecipe 파파레서피 주식회사 에이비티아시아
beauty107 원오세븐 (107 Beauty) 주식회사 소서
derma42 더마포티투 주식회사 에이티지코퍼레이션
kopher 코페르 (KOPHER) (주)베스트이노베이션
pith 피쓰 (Pith) 주식회사 엠레드코스메틱
kyyb KYYB 주식회사비팩토리

설치

pip install -r requirements.txt

실행

python run.py --sites all
python run.py --sites paparecipe,derma42 --out output/sample.json

--sites에 넘길 수 있는 키: paparecipe, beauty107, derma42, kopher, pith, kyyb (각각 파파레서피, 원오세븐, 더마포티투, 코페르, 피쓰, KYYB).

동작 방식

  1. 목록 수집 (crawler/list_scraper.py): 사이트별 카테고리 목록 페이지를 페이지네이션 끝까지 순회하며 상품명/가격/이미지/상세링크를 모은다. 카페24 사이트마다 CSS 클래스가 달라서, 특정 셀렉터 대신 "상세페이지 링크를 포함한 <li>"를 상품 카드로 인식하는 방식으로 통일했다.
  2. 카테고리 분류 (crawler/category_classifier.py): 상품명 키워드로 SKIN_TONER/AMPOULE_SERUM/CREAM/MIST_OIL/CLEANSER 중 하나로 분류. CLEANSER는 폼/오일/밀크/워터 등 텍스처 구분 없이 "클렌저/클렌징" 키워드가 있으면 전부 포함한다 (2026-08-12 확정 — 처음엔 클렌징폼만 넣기로 했다가 스코프가 넓어졌다). 이 5개에 해당 없는 상품(선크림, 립밤, 패치 등)은 제외.
  3. 전성분 추출 (crawler/detail_scraper.py): 상세페이지에서 "전성분" 표기를 찾아 그 옆/아래에 있는 성분 목록 텍스트를 가져온다. 이 정보가 아예 없는 상품(사이트에 따라 흔함)은 건너뛴다.
  4. 성분 매칭 (crawler/ingredient_matcher.py): 전성분 텍스트에서 8개 타깃 성분 중 포함된 걸 전부 찾는다. Product.ingredient가 단일 FK라, 성분이 여러 개 매칭되면 같은 상품을 성분 개수만큼 row로 복제한다.

결과 데이터 (output/products_seed.json)

123 row (실제 상품 수 기준 50개). 성분 여러 개가 매칭된 상품은 성분 개수만큼 row가 나뉘어 있어서, row 수가 실제 상품 수보다 많다. 필수 필드(name/brand/category/ imageUrl/linkUrl/ingredientName) 미기입, 중복, 깨진 URL은 전수 검사해서 없는 것을 확인했다.

브랜드 row 수 비고
파파레서피 85 카테고리 URL이 상품 유형별로 분리돼 있어 자동 파이프라인으로 전체 수집 (그중 클렌저 4)
원오세븐 19 위와 동일
더마포티투 7 위와 동일
피쓰 12 상세 이미지 안의 전성분을 수동으로 읽어서 반영 (아래 "알려진 제약" 참고)
코페르, KYYB 0 전성분 고시 자체가 없어서 제외 (아래 참고)

성분별

성분 row 수
히알루론산 29
센텔라 29
판테놀 22
나이아신아마이드 21
세라마이드 19
비타민C 2
알로에 1
징크 0

카테고리별

카테고리 row 수
CREAM 49
AMPOULE_SERUM 36
SKIN_TONER 17
MIST_OIL 17
CLEANSER 4

수동 보강 데이터 (output/products_manual.json)

비타민C/알로에/징크는 6개 사이트만으로는 표본이 너무 적어서(위 표 참고), 팀원이 다른 브랜드에서 직접 찾은 상품 29개를 추가했다. 자동 크롤링 결과와 신뢰도가 다르다는 걸 파일명으로 구분할 수 있게 별도 파일로 뒀다.

29 row. imageUrl은 각 상품 링크에서 og:image 메타태그를 읽어와 채웠는데, 12개만 성공했고 나머지 17개는 null이다.

  • 13개는 올리브영 상품(직링크 또는 oy.run 단축링크로 결국 올리브영으로 연결)이라 403으로 막혔다 — 네이버 계열과 같은 봇 차단 이슈.
  • 4개(시드물 3개, 닥터에디션 1개)는 og:image가 있긴 했는데 확인해보니 사이트 공용 기본 이미지(placeholder)였다. 상품마다 달라야 할 이미지가 전부 똑같은 URL을 가리켜서 가짜로 판단하고 null 처리했다.

이미지가 없는 17개는 BE에서 imageUrl nullable 처리하거나, 팀원이 직접 이미지 URL을 채워야 한다.

성분별: 알로에 11, 징크 10, 비타민C 8 카테고리별: CREAM 12, AMPOULE_SERUM 8, CLEANSER 6, SKIN_TONER 2, MIST_OIL 1

카테고리는 표에 없어서 크롤러와 같은 상품명 키워드 규칙으로 분류했고, 판단이 애매했던 것들은 다음과 같이 처리했다 (전부 재확인 필요):

  • "젤"만 있고 스킨/토너/크림/미스트 키워드가 없는 수딩젤 5개(큐어 알로에 수딩젤, 아로마티카 수딩 알로에 베라 젤 등)는 CREAM으로 넣었다.
  • 구달 "청귤 비타C 잡티케어 패드 알파"는 이름에 "토너"가 없지만 토너패드로 보고 SKIN_TONER로 넣었다.
  • 시드물 "알로에 스킨 화이트닝 (미스트)"는 이름에 "스킨"이 있어 자동 로직이면 SKIN_TONER로 잘못 잡히지만, 실제 미스트 제품이라 MIST_OIL로 수동 보정했다.
  • CLEEVA "클리바 르 클레어 앰플"은 표에 성분이 "비타민"이라고만 적혀 있어(다른 행은 다 "비타민 C") 오타로 보고 비타민C로 넣었다.

알려진 제약

세 사이트(Pith, KYYB, KOPHER)는 자동 파이프라인(detail_scraper.py)이 상세페이지에서 "전성분" 텍스트를 못 찾는다. 근데 원인을 까보면 사이트마다 다르다.

  • KYYB, KOPHER: 상세페이지의 "구매안내" 탭을 직접 열어봐도 결제/배송/교환/ 서비스문의만 있고 전성분 고시 항목 자체가 텍스트로도 이미지로도 없다. 판매자가 아예 안 올린 것으로 보이고, 크롤러를 더 손봐도 구할 수 있는 데이터가 아니라서 그대로 제외 상태로 뒀다 (코페르 13개, KYYB 6개 후보 상품 모두 미매칭).
  • Pith: 텍스트로는 없지만, 상세 디자인 이미지 맨 마지막 장("Product information/ 상품정보 고시")에 전성분이 이미지로 박혀 있다. 대상 상품이 7개뿐이라(그중 1개는 화장품이 아니라 실리콘 키링 액세서리라 전성분 자체가 없어 제외) OCR/비전 API를 따로 붙이지 않고, 이미지를 직접 열어 읽어서 8개 성분에 매칭한 뒤 output/products_seed.json에 수동으로 반영했다 (crawler/detail_scraper.py 상단 docstring에 근거 기록). 그래서 Pith의 12개 row는 run.py를 다시 돌려도 재생성되지 않는다 — 재크롤링 시 유실되지 않게 주의할 것.
  • 네이버 스마트스토어 계열(드뿌띠, 뷰라페 등 5곳)은 JS 렌더링과 봇 차단이 강해 이 크롤러 범위에 포함하지 않았다.

최종 데이터 (output/products_final.json)

products_seed.json(자동 크롤링 123 row) + products_manual.json(수동 보강 29 row)를 합친 파일. BE에 실제로 넘기는 건 이 파일이다.

152 row.

카테고리별

카테고리 row 수
CREAM 61
AMPOULE_SERUM 44
SKIN_TONER 19
MIST_OIL 18
CLEANSER 10

성분별

성분 row 수
히알루론산 29
센텔라 29
판테놀 22
나이아신아마이드 21
세라마이드 19
알로에 12
비타민C 10
징크 10

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages