Naver爬虫被阻止的原因和解决方法

這篇文章涵蓋了導致無法爬取Naver的原因以及解決方法的核心內容。談到了Naver服務的爬取難度、封鎖方式、解決方法和API的應用。

824
Naver爬虫被阻止的原因和解决方法

네이버는单一网站,而是多个服务。每个服务的封锁级别各不相同。

阅读时间: 14分钟 | 截至2026年1月


核心摘要

Naver是占据韩国搜索市场约55%份额的最大门户网站。Naver购物、博客、咖啡厅、智能商店等服务的爬取需求非常多样化。

问题在于每个服务的封锁方式和难度完全不同。博客相对容易,而智能商店甚至需要解决验证码问题。"Naver爬虫"不是一个问题,而是与服务数量相同的独立问题。

本文涵盖内容:
- Naver各服务的爬取难度(从简单到困难)
- 各服务的封锁方式(为什么被封锁,技术上)
- 实际可行的解决方法(针对每个服务的定制代码示例)
- Naver API vs 爬虫(何时使用何种)


目录

  1. Naver各服务的爬取难度
  2. Naver的机器人封锁技术
  3. Naver购物爬取
  4. Naver博客爬取
  5. 智能商店爬取
  6. Naver咖啡厅爬取
  7. Naver地点爬取
  8. Naver官方API总结
  9. 使用爬取API服务一次解决
  10. 常见问题

1. Naver各服务的爬取难度

Naver在一个域名下拥有数十个服务。爬取难度各不相同。

服务 域名 难度 主要封锁方式 可使用requests
Naver搜索 search.naver.com 速率限制 △(部分)
Naver博客 blog.naver.com iframe结构 (可绕过)
Naver新闻 news.naver.com 速率限制
Naver购物 shopping.naver.com JavaScript渲染,内部API △(需要分析API)
Naver地点 m.place.naver.com JavaScript + 内部API △(需要分析API)
Naver咖啡厅 cafe.naver.com 需要登录,权限检查 (大部分)
智能商店 smartstore.naver.com 验证码,JavaScript挑战
Naver支付 pay.naver.com 登录 + 安全令牌

核心模式: 与金钱直接相关的服务(智能商店,支付)通常安全性更高。


2. Naver的机器人封锁技术

与Coupang使用Akamai不同,Naver运营着自家开发的机器人封锁系统。由于外部解决方案的更新周期不规律,有时宽松,有时突然加强。

Naver的防御体系

요청 수신
  │
  ├─ Layer 1: robots.txt
  │    └─ Googlebot 등 주요 크롤러 외 대부분 차단
  │    └─ 실제 강제력은 없으나, 위반 시 법적 분쟁 불리
  │
  ├─ Layer 2: Rate Limiting
  │    └─ IP당 분당 요청 수 제한
  │    └─ 초과 시 일시 차단 (보통 5~30분)
  │
  ├─ Layer 3: JavaScript 렌더링 의존
  │    └─ 핵심 데이터를 JS로 동적 로드 (쇼핑, 플레이스)
  │    └─ SSR(서버 사이드 렌더링) 미적용 페이지가 많음
  │
  ├─ Layer 4: 캡챠 (스마트스토어 중심)
  │    └─ 의심스러운 접근에 네이버 자체 캡챠 표시
  │    └─ 최근 발생 빈도 증가 추세
  │
  └─ Layer 5: 로그인/권한 체크 (카페)
       └─ 회원 등급별 접근 제한
       └─ 비회원에게 본문 차단

Coupang vs Naver: 封锁级别比较

标准 Coupang Naver
机器人封锁解决方案 Akamai Bot Manager(外部) 自家开发
TLS指纹检查 (JA3/JA4哈希) (大部分)
JavaScript挑战 (全面应用) △(服务各不相同)
传感器数据收集 (_abck cookie)
验证码 智能商店偶尔有
使用requests访问 100%封锁 根据服务可行
总体难度 (平均)

结论: Naver总体上比Coupang容易,但根据服务不同,难度差异很大。博客爬取和智能商店爬取是完全不同的问题。


3. Naver购物爬取

结构理解

Naver购物采用SPA(单页应用程序)设计。在浏览器中显示的商品列表是在页面加载后由JavaScript调用内部API获取的。

브라우저가 shopping.naver.com 접속
  → 빈 HTML 프레임 로드
  → JavaScript 실행
  → 내부 API 호출 (shopping.naver.com/api/...)
  → JSON 응답 수신
  → 상품 카드 렌더링

因此,仅通过requests获取HTML将不会包含商品数据。有两种方法。

方法1: 直接调用内部API(最快,最有效)

在浏览器开发者工具(F12 → 网络选项卡)中查看Naver购物调用的API,并进行相同调用。

import requests

# 네이버 쇼핑 검색 내부 API
url = "https://shopping.naver.com/api/search"
params = {
    "query": "에어팟",
    "pagingIndex": 1,
    "pagingSize": 40,
    "sort": "rel"  # rel=관련도, price_asc=낮은가격, review=리뷰많은
}
headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",
    "Referer": "https://shopping.naver.com/search/all?query=에어팟"
}

response = requests.get(url, params=params, headers=headers)
data = response.json()

for item in data["shoppingResult"]["products"]:
    print(f"{item['productTitle']} - {item['price']}원 ({item['reviewCount']}건 리뷰)")

优点: 无需浏览器渲染,速度快,直接接收JSON
注意事项:
- 内部API端点/参数可能会被Naver*随时更改*
- 缺少Referer头将返回403
- 过多请求可能导致IP暂时封锁(建议请求间隔1-3秒)
- 实际API路径需要通过开发者工具定期确认

方法2: 使用Playwright进行浏览器渲染

如果内部API分析困难,或需要复杂的过滤/排序:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://shopping.naver.com/search/all?query=에어팟")

    # 상품 목록이 렌더링될 때까지 대기
    page.wait_for_selector('[class*="product_item"]', timeout=10000)

    products = page.query_selector_all('[class*="product_item"]')
    for product in products[:10]:
        title_el = product.query_selector('[class*="product_title"]')
        price_el = product.query_selector('[class*="price_num"]')
        if title_el and price_el:
            print(f"{title_el.inner_text()} - {price_el.inner_text()}")

    browser.close()

注意: Naver购物对无头浏览器的封锁程度不如Coupang(Akamai)那么严格,通常基本Playwright无头模式就能正常运行。但是,大量请求可能会导致IP封锁。

方法3: Naver购物搜索API(官方)

Naver开发者中心提供的免费官方API:

import requests

client_id = "YOUR_CLIENT_ID"      # 네이버 개발자센터에서 발급
client_secret = "YOUR_CLIENT_SECRET"

url = "https://openapi.naver.com/v1/search/shop.json"
headers = {
    "X-Naver-Client-Id": client_id,
    "X-Naver-Client-Secret": client_secret
}
params = {
    "query": "에어팟",
    "display": 100,    # 최대 100건
    "start": 1,        # 시작 위치 (최대 1000)
    "sort": "sim"      # sim=정확도, date=날짜, asc=가격오름, dsc=가격내림
}

response = requests.get(url, headers=headers, params=params)
data = response.json()

for item in data["items"]:
    # HTML 태그 제거 필요 (title에 <b> 태그 포함)
    import re
    clean_title = re.sub('<[^<]+?>', '', item['title'])
    print(f"{clean_title} - {item['lprice']}원 - {item['mallName']}")

官方API的局限性:
- 每天25,000次请求限制
- start参数最大为1,000 → 无法获取1,000个以上的数据
- 不包括详细规格、全部评论、卖家信息
- 无法按类别获取全部商品列表
- 没有实时库存/配送信息

→ 对于简单的价格比较或关键字趋势分析足够,但对于深入的数据分析则不足。


4. Naver博客爬取

结构特点: iframe

Naver博客自2003年起运营,保留了基于iframe的结构

blog.naver.com/username/포스트번호
  └─ 외부 프레임 (헤더, 프로필, 카테고리)
       └─ 내부 iframe (실제 글 내용)
            └─ PostView.naver?blogId=xxx&logNo=yyy

如果使用requests获取blog.naver.com/username/12345,将只获取外部框架的HTML,而不包含实际文章内容。需要直接调用iframe内的URL。

解决方法: 直接访问PostView URL

import requests
from bs4 import BeautifulSoup
import re

blog_id = "example_blog"
post_no = "223456789"

# 방법 A: PostView URL 직접 접근 (가장 간단)
url = f"https://blog.naver.com/PostView.naver?blogId={blog_id}&logNo={post_no}"
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..."}

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "html.parser")

# 스마트에디터 ONE (최신 에디터) 본문 추출
content = soup.select_one(".se-main-container")
if content:
    text = content.get_text(separator="\n", strip=True)
    print(text)

# 구 에디터 (이전 글들)
if not content:
    content = soup.select_one("#postViewArea")
    if content:
        text = content.get_text(separator="\n", strip=True)
        print(text)
# 방법 B: 메인 페이지에서 iframe URL 추출 후 접근
main_url = f"https://blog.naver.com/{blog_id}/{post_no}"
response = requests.get(main_url, headers=headers)
soup = BeautifulSoup(response.text, "html.parser")

# iframe src에서 logNo 추출
iframe = soup.select_one("iframe#mainFrame")
if iframe:
    iframe_src = iframe.get("src", "")
    # iframe_src를 파싱하여 PostView URL 구성
    print(f"iframe URL: https://blog.naver.com{iframe_src}")

从博客搜索结果中大量收集

import requests
import time

client_id = "YOUR_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"

# 1단계: 검색 API로 블로그 URL 목록 수집
search_url = "https://openapi.naver.com/v1/search/blog.json"
headers = {
    "X-Naver-Client-Id": client_id,
    "X-Naver-Client-Secret": client_secret
}
params = {"query": "크롤링 자동화", "display": 100, "start": 1}
response = requests.get(search_url, headers=headers, params=params)
blog_urls = [item["link"] for item in response.json()["items"]]

# 2단계: 각 블로그 글 본문 수집
for url in blog_urls:
    # blog.naver.com URL을 PostView URL로 변환
    # (URL 파싱 로직 필요)
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    soup = BeautifulSoup(response.text, "html.parser")
    content = soup.select_one(".se-main-container")
    if content:
        print(content.get_text(strip=True)[:200])
    time.sleep(2)  # Rate limiting 방지

注意事项

  • 私密/仅限好友的文章: 无登录cookie无法访问
  • 速率限制: 每分钟60~100篇以上将导致暂时封锁(建议1~2秒延迟)
  • 图片URL: Naver CDN(postfiles.pstatic.net)检查Referer → 直接下载图片时需要Referer: https://blog.naver.com
  • 编辑器版本: SmartEditor ONE(.se-main-container)与旧编辑器(#postViewArea)的HTML结构不同 → 需要同时处理两种

5. 智能商店爬取

为什么在Naver中最困难

智能商店是Naver的电子商务平台,与销售直接相关,因此安全性很高。

  • 完全的SPA: 所有商品信息都是通过JavaScript渲染的 — HTML中没有数据
  • 验证码出现: 短时间内访问多个页面时会显示Naver自身的验证码
  • 动态URL: smartstore.naver.com/{storename}/products/{productID}格式
  • API频繁更改: 内部API结构经常变化

智能商店内部API

智能商店也会调用内部REST API。可以在开发者工具中查看:

import requests

# 스마트스토어 상품 상세 API (내부 — 변경될 수 있음)
store_id = "store_channel_id"  # 상점의 채널 ID
product_id = "12345678"

api_url = f"https://smartstore.naver.com/i/v1/stores/{store_id}/products/{product_id}"
headers = {
    "User-Agent": "Mozilla/5.0 ...",
    "Referer": f"https://smartstore.naver.com/"
}

response = requests.get(api_url, headers=headers)
# 주의: 이 API는 차단되는 경우가 많음
# 성공하면 상품명, 가격, 옵션, 리뷰 수 등 JSON 반환

实际访问方法

规模 推荐方法 成功率 成本
少量(几十个) Playwright + 5~10秒延迟 70~90% 免费
中量(几百个) 爬取API服务 95%+ $35/月起
大量(数千个以上) 专业爬取服务 99%+ $99/月起
# 소량 수집: Playwright 사용
from playwright.sync_api import sync_playwright
import time

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)  # headless=False 권장
    page = browser.new_page()

    url = "https://smartstore.naver.com/example_store/products/12345678"
    page.goto(url)
    page.wait_for_load_state("networkidle")

    # 상품명
    title = page.query_selector('._3StrMSMN5r')  # 클래스명은 변경될 수 있음
    # 가격
    price = page.query_selector('._1LY7DqCnwR')

    if title and price:
        print(f"{title.inner_text()} - {price.inner_text()}")

    time.sleep(5)  # 캡챠 방지를 위한 딜레이
    browser.close()

重要: 智能商店的CSS类名经过混淆(哈希)处理,每次发布都会更改。建议首先使用data-testidaria-label等稳定选择器。


6. Naver咖啡厅爬取

主要问题: 登录 + 权限

Naver咖啡厅大部分帖子都是会员专用的。热门咖啡厅的等级限制非常严格。

접근 권한 구조:
  비회원  → 글 목록만 보임, 본문은 "카페 가입 후 이용" 메시지
  가입 회원 → 일부 게시판만 접근 가능
  등급 회원 → 전체 접근 가능 (활동 실적 필요)

自动登录的风险

Naver自动登录在技术上是可能的,但存在多个问题:

  • 键盘安全模块: naver.com登录时输入值会动态加密
  • 新设备验证: 首次在陌生环境登录时需要二次验证
  • 异常行为检测: 登录后检测到异常模式可能导致账户暂时停用
  • 违反服务条款: 自动登录违反Naver服务条款

→ 存在永久停用账户的风险,因此不建议使用。

合法替代方案

方法 描述 限制
Naver咖啡厅API 需要咖啡厅管理员批准API访问 需要管理员合作
手动登录 + 自动收集 手动在浏览器登录后,使用cookie自动收集 会话过期时需要重新登录
RSS订阅 某些咖啡厅论坛提供RSS 仅限最新帖子,仅部分内容
爬取API服务 提供咖啡厅爬取支持的服务 付费

7. Naver地点爬取

Naver地点(地图)包含商家信息、评论、访问人数等本地业务数据。

结构

Naver地点基于移动Web,通过内部API加载数据:

m.place.naver.com/restaurant/1234567890
  → JavaScript 로드
  → 내부 GraphQL API 호출
  → 가게 정보, 리뷰, 사진 등 렌더링

内部API利用

import requests

# 네이버 플레이스 내부 API (변경될 수 있음)
place_id = "1234567890"
api_url = f"https://api.place.naver.com/graphql"
headers = {
    "User-Agent": "Mozilla/5.0 ...",
    "Referer": f"https://m.place.naver.com/restaurant/{place_id}",
    "Content-Type": "application/json"
}

# GraphQL 쿼리 (실제 쿼리는 개발자도구에서 확인 필요)
query = {
    "operationName": "getPlaceDetail",
    "variables": {"id": place_id},
    "query": "query getPlaceDetail($id: String!) { ... }"
}

response = requests.post(api_url, headers=headers, json=query)
# 성공 시: 가게명, 주소, 전화번호, 영업시간, 평점, 리뷰 수 등

注意: Naver地点的GraphQL查询结构复杂且经常更改。如果需要稳定的收集,建议使用爬取API服务。


8. Naver官方API总结

请先查看Naver开发者中心(developers.naver.com)提供的API。免费且稳定。

可用API

API 日限制 主要数据 价格 发放
搜索(购物) 25,000次 商品名称、最低价、商店链接 免费 即时
搜索(博客) 25,000次 标题、摘要、URL 免费 即时
搜索(新闻) 25,000次 标题、摘要、发行商 免费 即时
搜索(咖啡厅) 25,000次 标题、摘要、咖啡厅名称 免费 即时
搜索(图片) 25,000次 图片URL、来源 免费 即时
Papago翻译 每日10,000字符 翻译结果 免费 即时
数据实验室(趋势) 1,000次 搜索词趋势(相对值) 免费 即时
地图/区域 单独 地点、坐标、导航 免费/付费 审核

如果API足够

  • 基于关键字的产品搜索 + 最低价比较
  • 搜索词趋势分析(Naver数据实验室)
  • 新闻/博客监控(关键字提醒)
  • 基本市场研究

如果API不足 → 需要爬取

  • 商品详细规格、全部评论文本收集
  • 按类别获取全部商品列表(超过1,000个)
  • 智能商店个别店铺的详细信息
  • 实时库存/配送信息
  • Naver地点商家详细信息(评论、访问人数)
  • 特定咖啡厅帖子收集

9. 使用爬取API服务一次解决

Naver的服务各不相同,封锁方式不同,API变化不定,甚至有验证码 — 如果要自行应对,需要不断修改代码。

使用爬取API服务,可以使用一个API来爬取所有Naver服务

一行代码爬取Naver

import requests

API_KEY = "your-api-key"

# 네이버 쇼핑
response = requests.post(
    "https://api.hashscraper.com/v1/scrape",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"url": "https://shopping.naver.com/search/all?query=에어팟", "format": "json"}
)
shopping_data = response.json()

# 스마트스토어 (캡챠 자동 처리)
response = requests.post(
    "https://api.hashscraper.com/v1/scrape",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"url": "https://smartstore.naver.com/example/products/12345", "format": "json"}
)
store_data = response.json()

# 네이버 블로그
response = requests.post(
    "https://api.hashscraper.com/v1/scrape",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"url": "https://blog.naver.com/example/223456789", "format": "json"}
)
blog_data = response.json()

为什么使用API服务:
- 无需担心各服务的封锁方式
- 自动处理验证码(智能商店)
- 自动JavaScript渲染
- 内部API更改也能适应
- 收到解析的JSON数据

使用AI代理爬取Naver

通过MCP,可以使用自然语言向AI提出请求:

Claude Desktop에서:

"네이버 쇼핑에서 '무선 이어폰' 검색해서 
 상위 20개 상품의 이름, 가격, 리뷰 수를 표로 정리해줘"

→ Claude가 HashScraper MCP를 호출하여 자동으로 수집 + 정리

这种方法无需编写代码,即使非开发人员也可以利用Naver数据。有关设置方法,请参阅AI代理增加爬取功能教程


10. 常见问题

问: Naver爬取合法吗?

收集公开网页的公开信息(如产品价格、商家信息等)通常没有问题。但以下情况可能涉及法律纠纷:
- 自动收集需要登录的区域(如私密咖啡厅帖子)
- 在robots.txt禁止的情况下进行大

Comments

Add Comment

Your email won't be published and will only be used for reply notifications.

继续阅读

Get notified of new posts

We'll email you when 해시스크래퍼 기술 블로그 publishes new content.

Your email will only be used for new post notifications.