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

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 | 방문자수: 155
LinkedIn Instagram
의견 혹은 질문을 남겨주세요. (0)

아직 의견이 없습니다.

관련 콘텐츠

도구가 작동하는 방식이 바뀌고 있다.

최근들어 몇몇 프로젝트를 인공지능 서비스인 claude를 사용하여 진행하고 있다. 이종호 님의 강2026년 제주 발표…

자동으로 insta_toons를 만들고 발행해주는 claude skill 입니다.

toons 디렉토리를 생성한 후에 public>character_sheet, public>episodes, public>referenc…

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

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…