페이지를 불러오는 중입니다...

Airbnb 마케팅 포인트 도출 스킬 공개합니다.
Airbnb 마케팅 포인트 도출 스킬 공개합니다.

# 영종도 에어비앤비 주간 리서치 스킬 (Firecrawl MCP)

---

name: airbnb-research

description: 매주 영종도 커플 숙소 시장을 리서치하여 리뷰 수집 → 문제 분석 → 오퍼 설계 → 바이럴 전략 → 경쟁사 분석을 자동화하고, 결과를 MD 파일과 React 컴포넌트로 저장하는 스킬. "에어비앤비 리서치 해줘", "영종도 숙소 분석 해줘", "airbnb 리서치", "airbnb.tsx 업데이트" 같은 요청 시 사용.

---

## 0. Firecrawl MCP 사전 확인 (필수)

**실행 전 반드시 확인:**

Firecrawl MCP가 연결되어 있지 않으면 스크래핑이 불가능합니다.

```

확인 방법: /mcp 명령으로 firecrawl 상태 확인

연결 안 된 경우: /mcp 로 reconnect 후 재시도

```

Firecrawl 도구를 호출하기 전에 `ToolSearch`로 스키마를 로드하세요:

```

ToolSearch query: "select:mcp__firecrawl__firecrawl_search,mcp__firecrawl__firecrawl_scrape,mcp__firecrawl__firecrawl_map"

```

도구 호출이 실패하거나 응답이 없으면 — **즉시 중단하고 사용자에게 `/mcp` 로 Firecrawl을 reconnect하도록 안내하세요.** 절대 mock 데이터를 사용하지 마세요.

---

## 1. 실행 순서 개요

```

STEP 1 → Airbnb 리스팅 검색 (firecrawl_search × 3 병렬)

STEP 2 → 상위 숙소 5곳 리뷰 스크래핑 (firecrawl_scrape × 5 순차)

STEP 3 → 중간 저장: docs/airbnb-yeongjonge-YYYY-MM-DD.md

STEP 4 → 문제 분석: 긴급도 + WTP 점수화

STEP 5 → 고전환 오퍼 5개 설계

STEP 6 → 바이럴 콘텐츠 전략 (훅 20개 + SPICE 구조)

STEP 7 → 경쟁사 5개 분석 + 시장 장악 전략

STEP 8 → 전체 세션 MD 저장: docs/session-YYYY-MM-DD.md

STEP 9 → React 컴포넌트 생성: src/components/Trends/airbnb.tsx

```

---

## 2. STEP 1 — Airbnb 리스팅 검색

**병렬로 3개 검색 실행:**

```

Query 1: "영종도 커플 오션뷰 숙소 에어비앤비" site:airbnb.co.kr

Query 2: "인천 중구 2인 스테이 오션뷰 airbnb" site:airbnb.co.kr  

Query 3: "영종도 호캉스 커플 베스트 숙소 후기"

```

`firecrawl_search` 파라미터:

```json

{

  "query": "...",

  "limit": 8,

  "lang": "ko",

  "country": "kr"

}

```

상위 결과에서 `/rooms/` 경로를 포함한 URL 5개를 선별합니다.

커플 특화, 오션뷰, 2인 키워드가 포함된 리스팅을 우선합니다.

---

## 3. STEP 2 — 리뷰 스크래핑 (숙소 5곳)

각 숙소 URL에 대해 `firecrawl_scrape` 실행:

```json

{

  "url": "https://www.airbnb.co.kr/rooms/XXXXXXXXX",

  "formats": ["markdown"],

  "actions": [{"type": "wait", "milliseconds": 5000}],

  "proxy": "stealth",

  "headers": {

    "Accept-Language": "ko-KR,ko;q=0.9",

    "X-Forwarded-For": "211.36.140.1"

  }

}

```

**JSON 형식이 리뷰를 반환하지 않는 경우**: `formats: ["markdown"]`으로 전환하여 페이지 전체 텍스트에서 리뷰를 추출합니다. Airbnb는 SPA이므로 `waitFor: 5000`이 필수입니다.

각 숙소에서 추출할 정보:

- 숙소명, 평점, 후기 수, 유형, URL

- 실제 후기 텍스트 최소 5개 (별점 3~5점 혼합)

- 키워드 요약 (칭찬 / 불만 / 기대 초과 / 재방문 의향)

---

## 4. STEP 3 — 중간 저장: 리뷰 MD 파일

**파일 경로:** `docs/airbnb-yeongjonge-YYYY-MM-DD.md`

형식은 아래를 따릅니다:

```markdown

# 영종도 에어비앤비 커플 오션스테이 리뷰 — YYYY-MM-DD

> 검색어: 인천 / 영종도 / 중구 / 오션스테이 / 커플 / 2인

---

## 1. [숙소명]

- **URL**: https://www.airbnb.co.kr/rooms/XXXXXXXXX

- **평점**: ⭐X.XX | **후기 수**: N개 | **유형**: 아파트/원룸/투룸

- **태그**: #커플 #오션뷰 #...

### 리뷰

| 후기자 | 별점 | 내용 |

|--------|------|------|

| 이름   | ⭐5  | "후기 내용..." |

| ...    | ...  | ...           |

**키워드 요약:** 칭찬: `뷰`, `청결` / 불만: `방음`, `청소의무` / 기대 초과: `호스트 친절` / 재방문: O

---

```

**숙소 5곳 완료 후 즉시 파일을 저장합니다. (Write 도구 사용)**

마지막에 종합 인사이트 테이블 추가:

```markdown

## 종합 인사이트

| 항목 | 내용 |

|------|------|

| 평균 평점 | X.XX |

| 가장 많은 칭찬 | ... |

| 가장 많은 불만 | ... |

| 업계 공통 문제 | ... |

| 기회 포인트 | ... |

```

---

## 5. STEP 4 — 문제 분석

리뷰 MD를 바탕으로 숙소 문제 TOP 10을 도출합니다.

**점수화 기준:**

| 기호 | 의미 |

|------|------|

| 🔴 | 리뷰에서 실제 불평 등장 |

| 🚀 | 빠르게 커지는 니즈 (OTT, 시간 유연성 등) |

| 긴급도 | 투숙 중 즉각 불쾌감 (1~10) |

| WTP | 해결 시 기꺼이 돈 낼 의향 (1~10) |

**출력 형식:**

```markdown

| # | 문제 | 긴급도 | WTP | 신호 |

|---|------|:------:|:---:|------|

| 1 | ... | 9 | 9 | 🔴 🚀 |

...

```

우선순위 매트릭스도 포함:

```

긴급도 높음 + WTP 높음 → 즉시 해결 가치

긴급도 보통 + WTP 높음 → 선점 기회

실제 별점 깎는 문제 → 리스크 관리 필요

```

---

## 6. STEP 5 — 고전환 오퍼 5개

긴급도 × WTP가 높은 상위 5개 문제에 대해 각각:

```markdown

### OFFER N — "[오퍼 이름]"

**문제: ...** (긴급 X / WTP X)

**🎯 이상적인 고객**

| 항목 | 정의 |

|------|------|

| 인구통계 | 나이, 직업, 여행 목적 |

| 심리 | "..." (내면의 말) |

| 핵심 욕구 | ... |

**💎 가치 제안**

헤드라인 + 2~3줄 설명

**💰 가격 전략**

| 티어 | 내용 | 가격 |

|------|------|------|

**🛡️ 보상 + 리스크 제거**

- 조건 → 보상

**🏆 경쟁사보다 나은 이유**

| | 에어비앤비 | 호텔 | 이 오퍼 |

|--|--|--|--|

```

---

## 7. STEP 6 — 바이럴 콘텐츠 전략

### 고전환 훅 20개

감정 유형별로 분류:

- 🔴 공포 (Fear) — 4개

- 💢 분노 (Outrage) — 4개

- 🧠 호기심 (Curiosity) — 4개

- 👑 지위 (Status) — 3개

- 💔 공감 (Empathy) — 3개

- ⚡ 반전 (Reframe) — 2개

### 감정 트리거 맵

```

감정 → 트리거 메시지 → 반응 행동 (저장/공유/클릭/댓글)

```

### SPICE 바이럴 구조

S(Stop) → P(Pain) → I(Insight) → C(Claim) → E(Engage) 형식으로 3개 예시 작성.

### 플랫폼별 전략

인스타그램 / 틱톡 / 네이버 블로그 / 카카오 오픈채팅 / 유튜브 쇼츠

### 콘텐츠 반복 캘린더

요일별 감정 유형 배분 (월~일)

---

## 8. STEP 7 — 경쟁사 5개 분석

Firecrawl로 경쟁사 현황을 검색합니다 (병렬 3개):

```

Query A: "인스파이어 엔터테인먼트 리조트 영종도 커플 후기 2025"

Query B: "파라다이스시티 인천 커플 호캉스 후기"

Query C: "야놀자 여기어때 영종도 오션뷰 숙소 추천"

```

각 경쟁사 분석 형식:

```markdown

### 경쟁사 N — [이름]

| 항목 | 내용 |

|------|------|

| 잘하는 것 | ... |

| 약한 부분 | ... |

| 놓치고 있는 고객층 | ... |

| 포지셔닝 공백 | ... |

```

포지셔닝 맵 (가격 축 × 커플 큐레이션 축) 텍스트로 시각화.

**시장 장악 5단계 전략:**

1. 포지셔닝 선점

2. 유통 채널 구축

3. 호스트 파트너십

4. 콘텐츠 장악

5. 가격 전략

12개월 로드맵 포함.

---

## 9. STEP 8 — 전체 세션 MD 저장

**파일 경로:** `docs/session-YYYY-MM-DD.md`

```markdown

# 세션 기록 — YYYY-MM-DD

> 주제: 영종도 에어비앤비 리뷰 수집 → 문제 분석 → 오퍼 설계 → 바이럴 전략 → 경쟁사 분석

---

## Q1. 영종도 에어비앤비 리뷰 수집

[수집 숙소 테이블 + 참조 파일 경로]

## Q2. 숙소 문제 분석 및 점수화

[문제 매트릭스 전체]

## Q3. 고전환 오퍼 5개

[오퍼 1~5 전체]

## Q4. 바이럴 콘텐츠 전략

[훅 20개 + 감정 트리거 + SPICE + 캘린더]

## Q5. 경쟁사 5개 분석 및 시장 장악 전략

[경쟁사 분석 전체 + 로드맵]

---

*생성일: YYYY-MM-DD | 도구: Claude + Firecrawl MCP | 데이터: airbnb.co.kr 실시간 스크래핑*

```

**Write 도구로 즉시 저장합니다.**

---

## 10. STEP 9 — React 컴포넌트 생성

**출력 파일:** `src/components/Trends/airbnb.tsx` (덮어쓰기)

기본 export 이름: `AirbnbResearch`

```ts

// App.tsx import:

import AirbnbResearch from "./components/Trends/airbnb";

```

### Fashion.tsx 스타일 지침

`Fashion.tsx`와 동일한 시각적 언어를 사용합니다:

- **배경**: `bg-white min-h-screen font-sans text-slate-900`

- **히어로**: 검은 배경 + 오션뷰 이미지 오버레이 + 세리프 이탤릭 대형 제목

- **카드**: `rounded-xl`, hover shadow, `group-hover:scale-105` 이미지 줌

- **섹션 제목**: `text-5xl font-serif mb-2 border-b pb-4`

- **배지**: 각 섹션별 색상 — 문제: `bg-red-100 text-red-700`, 오퍼: `bg-blue-100 text-blue-700`, 바이럴: `bg-purple-100 text-purple-700`

- **하단**: 키워드 태그 + 스타일링 팁 박스 (`bg-slate-50 p-12 rounded-3xl`)

- **라이트박스**: ESC + 클릭 닫기 (외부 라이브러리 없음)

### 컴포넌트 섹션 구조

```tsx

import React from 'react';

type LightboxState = { src: string; title: string; tag: string } | null;

// ── 데이터 ──────────────────────────────────────────────

const listings = [

  {

    name: "숙소명",

    rating: 4.97,

    reviewCount: 243,

    type: "아파트 투룸",

    url: "https://www.airbnb.co.kr/rooms/...",

    image: "https://...",  // 숙소 대표 이미지 URL

    tags: ["#커플데이트", "#오션뷰"],

    summary: "2~3문장 숙소 특징 요약",

    topComplaint: "가장 많은 불만 키워드",

    topPraise: "가장 많은 칭찬 키워드",

  },

  // ... 5곳

];

const problemMatrix = [

  {

    rank: 1,

    problem: "체크아웃 청소 의무 과다",

    urgency: 9,

    wtp: 9,

    flags: ["🔴", "🚀"],

    quote: "\"청소비 내고 나서 설거지까지 해야 함\"",

  },

  // ... 10개

];

const offers = [

  {

    title: "No-Chore Checkout",

    problem: "체크아웃 청소 의무 과다",

    urgency: 9,

    wtp: 9,

    headline: "청소는 우리가, 마지막 아침은 당신이",

    description: "퇴실 전 설거지, 분리수거, 수건 정리 일절 필요 없음.",

    tiers: [

      { name: "기본", desc: "청소비 포함", price: "예약 시 포함" },

      { name: "노-초어", desc: "청소 의무 면제 + 1h 레이트 체크아웃", price: "+₩15,000" },

      { name: "프리미엄", desc: "노-초어 + 2h 레이트 + 조식", price: "+₩39,000" },

    ],

    guarantee: "퇴실 후 추가 청구 없음 보장",

    tags: ["#NoChore", "#레이트체크아웃"],

  },

  // ... 5개

];

const viralHooks = [

  { emotion: "공포", text: "영종도 에어비앤비 예약 전, 이것 하나만 확인하세요.", color: "red" },

  { emotion: "분노", text: "청소비 4만원 내고, 퇴실 전 쓰레기 분리수거까지 해야 합니다.", color: "orange" },

  // ... 20개

];

const competitors = [

  {

    name: "에어비앤비 플랫폼",

    strength: "최다 선택지, 후기 시스템",

    weakness: "품질 보장 없음, 커플 큐레이션 부재",

    missingSegment: "기념일 커플 — 선택 피로 세그먼트",

    gap: "커플 전용 큐레이션 채널",

    priceRange: "₩8~20만",

  },

  // ... 5개

];

// ── 컴포넌트 ──────────────────────────────────────────────

const AirbnbResearch: React.FC = () => {

  const [lightbox, setLightbox] = React.useState<LightboxState>(null);

  const [activeTab, setActiveTab] = React.useState<'listings' | 'problems' | 'offers' | 'viral' | 'competitors'>('listings');

  React.useEffect(() => {

    const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setLightbox(null); };

    window.addEventListener('keydown', handler);

    return () => window.removeEventListener('keydown', handler);

  }, []);

  return (

    <div className="bg-white min-h-screen font-sans text-slate-900">

      {/* Hero */}

      <header className="relative h-[80vh] flex items-center justify-center overflow-hidden bg-black">

        <img

          src="{{HERO_IMAGE — 오션뷰 숙소 대표 이미지}}"

          className="absolute inset-0 w-full h-full object-cover opacity-50"

          alt="영종도 오션뷰"

        />

        <div className="relative z-10 text-center px-4">

          <p className="text-white text-xs tracking-[0.5em] uppercase opacity-60 mb-4">영종도 커플 호캉스 · {TODAY_DATE}</p>

          <h1 className="text-white text-6xl md:text-9xl font-serif italic mb-4">Market Report</h1>

          <p className="text-white text-xl tracking-[0.3em] uppercase opacity-80">Airbnb Intelligence</p>

        </div>

      </header>

      {/* Tab Navigation */}

      <nav className="sticky top-0 z-40 bg-white border-b border-slate-200 shadow-sm">

        <div className="max-w-7xl mx-auto px-6 flex gap-1 overflow-x-auto py-3">

          {[

            { key: 'listings', label: '🏠 숙소 리뷰' },

            { key: 'problems', label: '🔴 문제 분석' },

            { key: 'offers', label: '💎 고전환 오퍼' },

            { key: 'viral', label: '⚡ 바이럴 전략' },

            { key: 'competitors', label: '🏆 경쟁사 분석' },

          ].map(tab => (

            <button

              key={tab.key}

              onClick={() => setActiveTab(tab.key as typeof activeTab)}

              className={`px-4 py-2 rounded-lg text-sm font-medium whitespace-nowrap transition-colors ${

                activeTab === tab.key

                  ? 'bg-slate-900 text-white'

                  : 'text-slate-600 hover:bg-slate-100'

              }`}

            >

              {tab.label}

            </button>

          ))}

        </div>

      </nav>

      <main className="max-w-7xl mx-auto px-6 py-16">

        {/* ── TAB: 숙소 리뷰 ── */}

        {activeTab === 'listings' && (

          <section>

            <h2 className="text-5xl font-serif mb-2 border-b pb-4">🏠 영종도 커플 오션스테이</h2>

            <p className="text-slate-500 text-sm tracking-widest uppercase mb-10">Airbnb 실시간 리뷰 수집 · {TODAY_DATE}</p>

            <div className="grid grid-cols-1 md:grid-cols-3 gap-6">

              {listings.map((item, i) => (

                <div

                  key={i}

                  className="group cursor-zoom-in overflow-hidden rounded-xl bg-slate-50 hover:shadow-xl transition-shadow duration-300"

                  onClick={() => setLightbox({ src: item.image, title: item.name, tag: item.tags[0] })}

                >

                  <div className="overflow-hidden h-48">

                    <img src={item.image} alt={item.name}

                      className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />

                  </div>

                  <div className="p-5">

                    <div className="flex items-center justify-between mb-2">

                      <span className="text-amber-500 font-bold">⭐{item.rating}</span>

                      <span className="text-slate-400 text-xs">{item.reviewCount}개 후기</span>

                    </div>

                    <h4 className="font-serif text-lg mb-1 leading-snug">{item.name}</h4>

                    <p className="text-slate-500 text-xs mb-3">{item.type}</p>

                    <p className="text-slate-600 text-sm leading-relaxed mb-3">{item.summary}</p>

                    <div className="flex flex-wrap gap-1 mb-3">

                      {item.tags.map((tag, j) => (

                        <span key={j} className="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full">{tag}</span>

                      ))}

                    </div>

                    <div className="text-xs text-slate-500 space-y-1">

                      <div>👍 {item.topPraise}</div>

                      <div>👎 {item.topComplaint}</div>

                    </div>

                  </div>

                </div>

              ))}

            </div>

          </section>

        )}

        {/* ── TAB: 문제 분석 ── */}

        {activeTab === 'problems' && (

          <section>

            <h2 className="text-5xl font-serif mb-2 border-b pb-4">🔴 숙소 문제 매트릭스</h2>

            <p className="text-slate-500 text-sm tracking-widest uppercase mb-10">긴급도 × WTP 점수화 · 리뷰 기반</p>

            <div className="space-y-4">

              {problemMatrix.map((item, i) => (

                <div key={i} className="flex items-start gap-4 p-5 rounded-xl bg-slate-50 hover:bg-slate-100 transition-colors">

                  <span className="text-2xl font-bold text-slate-300 w-8 flex-shrink-0">#{item.rank}</span>

                  <div className="flex-1">

                    <div className="flex items-center gap-2 mb-1">

                      <h4 className="font-serif text-lg">{item.problem}</h4>

                      {item.flags.map((f, j) => <span key={j} className="text-base">{f}</span>)}

                    </div>

                    <p className="text-slate-500 text-sm italic mb-2">{item.quote}</p>

                    <div className="flex gap-4">

                      <div className="text-sm">

                        <span className="text-slate-400">긴급도 </span>

                        <span className="font-bold text-red-600">{item.urgency}/10</span>

                      </div>

                      <div className="text-sm">

                        <span className="text-slate-400">WTP </span>

                        <span className="font-bold text-emerald-600">{item.wtp}/10</span>

                      </div>

                    </div>

                  </div>

                  <div className="flex-shrink-0 text-right">

                    <div

                      className="w-16 h-16 rounded-full flex items-center justify-center text-white font-bold text-lg"

                      style={{ background: `hsl(${Math.round((item.urgency + item.wtp) / 2) * 6}, 70%, 45%)` }}

                    >

                      {item.urgency + item.wtp}

                    </div>

                  </div>

                </div>

              ))}

            </div>

          </section>

        )}

        {/* ── TAB: 고전환 오퍼 ── */}

        {activeTab === 'offers' && (

          <section>

            <h2 className="text-5xl font-serif mb-2 border-b pb-4">💎 고전환 오퍼 설계</h2>

            <p className="text-slate-500 text-sm tracking-widest uppercase mb-10">Top 5 문제 · 이상적 고객 정의 · 보장 포함</p>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-8">

              {offers.map((offer, i) => (

                <div key={i} className="rounded-xl border border-slate-200 overflow-hidden hover:shadow-lg transition-shadow">

                  <div className="bg-slate-900 text-white p-5">

                    <p className="text-slate-400 text-xs tracking-widest uppercase mb-1">OFFER {i + 1} · 긴급 {offer.urgency} / WTP {offer.wtp}</p>

                    <h4 className="font-serif text-2xl italic mb-1">{offer.title}</h4>

                    <p className="text-slate-300 text-sm">{offer.headline}</p>

                  </div>

                  <div className="p-5 space-y-4">

                    <p className="text-slate-600 text-sm leading-relaxed">{offer.description}</p>

                    <div>

                      <p className="text-xs text-slate-400 uppercase tracking-widest mb-2">가격 티어</p>

                      <div className="space-y-2">

                        {offer.tiers.map((tier, j) => (

                          <div key={j} className="flex justify-between items-center text-sm">

                            <div>

                              <span className="font-medium">{tier.name}</span>

                              <span className="text-slate-500 ml-2">{tier.desc}</span>

                            </div>

                            <span className="font-bold text-blue-700">{tier.price}</span>

                          </div>

                        ))}

                      </div>

                    </div>

                    <div className="bg-emerald-50 rounded-lg p-3">

                      <p className="text-xs text-emerald-700 font-medium">🛡️ {offer.guarantee}</p>

                    </div>

                    <div className="flex flex-wrap gap-1">

                      {offer.tags.map((tag, j) => (

                        <span key={j} className="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full">{tag}</span>

                      ))}

                    </div>

                  </div>

                </div>

              ))}

            </div>

          </section>

        )}

        {/* ── TAB: 바이럴 전략 ── */}

        {activeTab === 'viral' && (

          <section>

            <h2 className="text-5xl font-serif mb-2 border-b pb-4">⚡ 바이럴 콘텐츠 전략</h2>

            <p className="text-slate-500 text-sm tracking-widest uppercase mb-10">고전환 훅 20개 · SPICE 구조 · 플랫폼별 전략</p>

            <div className="columns-1 md:columns-2 gap-6 space-y-4">

              {viralHooks.map((hook, i) => {

                const colorMap: Record<string, string> = {

                  red: 'bg-red-50 border-red-200 text-red-800',

                  orange: 'bg-orange-50 border-orange-200 text-orange-800',

                  purple: 'bg-purple-50 border-purple-200 text-purple-800',

                  blue: 'bg-blue-50 border-blue-200 text-blue-800',

                  pink: 'bg-pink-50 border-pink-200 text-pink-800',

                  amber: 'bg-amber-50 border-amber-200 text-amber-800',

                };

                return (

                  <div key={i} className={`break-inside-avoid p-4 rounded-xl border mb-4 ${colorMap[hook.color] || colorMap.blue}`}>

                    <div className="flex items-center gap-2 mb-2">

                      <span className="text-xs font-bold opacity-60 uppercase tracking-widest">#{String(i + 1).padStart(2, '0')}</span>

                      <span className="text-xs font-medium opacity-70">{hook.emotion}</span>

                    </div>

                    <p className="text-sm font-medium leading-relaxed">"{hook.text}"</p>

                  </div>

                );

              })}

            </div>

          </section>

        )}

        {/* ── TAB: 경쟁사 분석 ── */}

        {activeTab === 'competitors' && (

          <section>

            <h2 className="text-5xl font-serif mb-2 border-b pb-4">🏆 경쟁사 5개 분석</h2>

            <p className="text-slate-500 text-sm tracking-widest uppercase mb-10">포지셔닝 공백 · 시장 장악 전략</p>

            <div className="space-y-6">

              {competitors.map((comp, i) => (

                <div key={i} className="p-6 rounded-xl bg-slate-50 hover:bg-slate-100 transition-colors">

                  <div className="flex items-start justify-between mb-4">

                    <div>

                      <span className="text-slate-400 text-xs font-bold uppercase tracking-widest">경쟁사 {i + 1}</span>

                      <h4 className="font-serif text-2xl mt-1">{comp.name}</h4>

                    </div>

                    <span className="text-sm text-slate-500 bg-white px-3 py-1 rounded-full border">{comp.priceRange}</span>

                  </div>

                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">

                    <div>

                      <p className="text-xs text-slate-400 uppercase tracking-wider mb-1">잘하는 것</p>

                      <p className="text-slate-700 leading-relaxed">{comp.strength}</p>

                    </div>

                    <div>

                      <p className="text-xs text-slate-400 uppercase tracking-wider mb-1">약한 부분</p>

                      <p className="text-slate-700 leading-relaxed">{comp.weakness}</p>

                    </div>

                    <div>

                      <p className="text-xs text-slate-400 uppercase tracking-wider mb-1">놓치는 고객층</p>

                      <p className="text-slate-700 leading-relaxed">{comp.missingSegment}</p>

                    </div>

                    <div>

                      <p className="text-xs text-red-400 uppercase tracking-wider mb-1">포지셔닝 공백 ★</p>

                      <p className="text-red-700 font-medium leading-relaxed">{comp.gap}</p>

                    </div>

                  </div>

                </div>

              ))}

            </div>

          </section>

        )}

        {/* Bottom Summary */}

        <section className="mt-24 bg-slate-50 p-12 rounded-3xl">

          <div className="grid md:grid-cols-2 gap-12">

            <div>

              <h4 className="text-2xl font-serif mb-6 underline underline-offset-4">핵심 기회 키워드</h4>

              <div className="flex flex-wrap gap-2">

                {/* 스크래핑 결과에서 추출한 주요 키워드들 */}

              </div>

            </div>

            <div>

              <h4 className="text-2xl font-serif mb-6 underline underline-offset-4">이번 주 액션 아이템</h4>

              <ul className="space-y-3 text-slate-600">

                {/* 분석 결과 기반 실행 항목들 */}

              </ul>

            </div>

          </div>

        </section>

      </main>

      {/* Lightbox */}

      {lightbox && (

        <div

          className="fixed inset-0 z-50 bg-black/90 flex flex-col items-center justify-center cursor-zoom-out"

          onClick={() => setLightbox(null)}

        >

          <button

            className="absolute top-6 right-8 text-white text-4xl leading-none hover:opacity-70"

            onClick={() => setLightbox(null)}

          >×</button>

          <img

            src={lightbox.src}

            alt={lightbox.title}

            className="max-h-[85vh] max-w-[90vw] object-contain rounded-xl"

            onClick={(e) => e.stopPropagation()}

          />

          <div className="mt-6 text-center">

            <p className="text-white font-serif text-xl">{lightbox.title}</p>

            <p className="text-slate-400 text-sm mt-1 tracking-widest uppercase">{lightbox.tag}</p>

          </div>

        </div>

      )}

      <footer className="text-center py-12 text-slate-400 text-xs tracking-widest uppercase border-t border-slate-100">

        Generated {TODAY_DATE} · Airbnb Market Intelligence · Firecrawl MCP

      </footer>

    </div>

  );

};

export default AirbnbResearch;

```

**실제 데이터로 채울 때:**

- `listings[]` — Airbnb 스크래핑 결과로 채움 (숙소별 대표 이미지 URL 필수)

- `problemMatrix[]` — 리뷰 분석 결과로 채움 (10개)

- `offers[]` — 오퍼 설계 결과로 채움 (5개)

- `viralHooks[]` — 훅 20개 채움 (감정 유형 + 색상 지정)

- `competitors[]` — 경쟁사 5개 채움

- `TODAY_DATE` → 실제 날짜 문자열로 교체

---

## 11. 운영 규칙

### 필수 규칙

- **Firecrawl 먼저**: 내부 지식으로 데이터를 만들지 않습니다. 반드시 실시간 스크래핑.

- **Firecrawl 실패 시**: mock 데이터 금지. 사용자에게 `/mcp` reconnect 요청.

- **중간 저장**: 리뷰 MD는 STEP 3에서 즉시 저장. 컨텍스트 손실 방지.

- **실제 URL만**: 접근 불가능한 이미지 URL 삽입 금지.

- **airbnb.co.kr 기준**: 검색은 한국 Airbnb 기준.

### 파일 저장 체크리스트

```

□ docs/airbnb-yeongjonge-YYYY-MM-DD.md  — STEP 3에서 저장

□ docs/session-YYYY-MM-DD.md            — STEP 8에서 저장  

□ src/components/Trends/airbnb.tsx      — STEP 9에서 저장 (덮어쓰기)

```

### 로그 기록

실행 완료 후 한 줄 로그 추가:

```bash

echo "[YYYY-MM-DD] airbnb-research: OK — N개 숙소, M개 리뷰 수집" >> /home/cakepower/tutorial/a14u/logs/airbnb-research.log

```

---

## 12. 자동화 주간 실행

이 스킬은 **매주 월요일 08:00 KST** 에 자동 실행됩니다.

### Cron 등록

```bash

0 8 * * 1 cd /home/cakepower/tutorial/a14u && claude --print "에어비앤비 리서치 해줘" >> /home/cakepower/tutorial/a14u/logs/airbnb-research.log 2>&1

```

### 자동 실행 시 필수 동작

1. Firecrawl MCP 연결 확인 → 안 되면 스크립트 종료 (mock 금지)

2. 영종도 커플 숙소 5곳 스크래핑

3. 문제 분석 → 오퍼 → 바이럴 → 경쟁사 분석 순서로 실행

4. MD 파일 2개 저장 (리뷰 + 세션)

5. `src/components/Trends/airbnb.tsx` 덮어쓰기

6. 로그 1줄 기록

7. `npm run build` 또는 git commit **자동 실행 금지**

### 로그 위치

```

/home/cakepower/tutorial/a14u/logs/airbnb-research.log

```

### Cron 등록 확인

```bash

crontab -l | grep airbnb-research

```

작성일: 2026-04-18 | 카테고리: Playing with AI | 방문자수: 25
LinkedIn Instagram
의견 혹은 질문을 남겨주세요. (0)

아직 의견이 없습니다.

관련 콘텐츠

애니메이션 카드 뉴스 생성 스킬 정리

1) newsletter.md 파일 # 뉴스레터 작성 스킬 업계 소식을 큐레이션하여 구독자에게 가치 있는 마크다운 뉴스레터를 작성하…

Fashion Trend를 조사, 분석 리포트까지 작성하는 Skill

# Fashion Trend React Component Generator Skill (with Firecrawl MCP) You…

카드 뉴스를 발행하는 skill 정리합니다.

https://www.threads.com/@06am_draw/post/DV7DjOsihwk?xmt=AQF00wmvK6QkpssJhCKyfaI…

인공지능을 활용할 때 주의할 점은?

"지금 우리는 아주 말을 잘 알아듣는 컴퓨터에게 아주 인간의 말을 잘 알아듣지 못하는 컴퓨터를 위한 일을 시키기 위한 방법을 배우고 있다" 라…

Nano Banana 를 통한 채색 Upgrade

Your browser does not support the video t…

Beautiful Antigravity

Antigravity를 사용해 본 후에, 싸~~한 느낌이 들어서 곰곰히 생각해 봤어. 지금까지 내가 chatGPT나 Perflexity를…

드디어 A14U = 당신을 위한 AI 매거진의 틀이 완성되었습니다.

2026년 1월 8일 그동안 Vibe Coding 을 실천하면서 목표로 삼은 것이 내가 지금 작성한 HTML 기반의 웹사이트를 React…

이뭣꼬?

하라켄야의 디자인 교육법에서 영감을 얻어 간화선(看話禪) 을 탐구하고 있습니다. 간화선은 화두(話頭)를 통해 깨달음을 …

Higgsfield AI 활용하는 법

일단 작업 전체는 Figma 링크 에 정리해놨어. 왼쪽 Figma 링크 버튼을 누르면 전체 작업 프로세스를 볼 수 있을거야. 나…