如何在2026年抓取Pinterest图钉和看板:开发者完整指南

详解Pinterest内部Resource API端点、住宅代理轮换策略、Python和Node.js代码示例,帮助开发者合法高效地采集公开图钉和看板数据。

How to Scrape Pinterest Pins and Boards in 2026: A Developer's Guide
本文目录

如何在2026年抓取Pinterest图钉和看板:开发者完整指南

如果你正在构建视觉内容数据集、趋势分析平台或竞品监控系统,Pinterest 是一个极具价值的数据源——它拥有超过 5 亿月活跃用户和海量的视觉发现数据。然而,Pinterest 的反爬机制、本地化搜索结果和内部 API 结构使得大规模数据采集充满挑战。本文将深入讲解如何合法、高效地抓取 Pinterest 公开图钉(Pins)和看板(Boards),涵盖内部 Resource API 的工作原理、代理轮换策略以及生产环境中的最佳实践。

法律声明:本文仅涉及公开可访问数据的采集。在开始之前,请务必阅读并遵守 Pinterest 的服务条款(Terms of Service)。在美国,未经授权的数据访问可能违反《计算机欺诈和滥用法》(CFAA);在欧盟,处理个人数据须遵守《通用数据保护条例》(GDPR)。如果你需要采集的数据涉及个人信息或需要登录才能访问,请优先使用 Pinterest 官方 API v5

公开数据 vs 登录墙:你能抓什么?

Pinterest 的数据表面可以分为两类:

  • 公开数据(无需登录):公开看板的图钉流、图钉详情页、公开搜索结果、用户公开个人资料页。这些页面在浏览器中无需登录即可访问。
  • 登录墙数据:首页推荐流(home feed)、个性化推荐、私密看板、已保存的图钉。这些内容需要用户登录并依赖个性化算法,不适合也不应通过爬虫获取。

Pinterest 提供了 官方 API v5,允许开发者通过 OAuth 获取用户授权的看板和图钉数据。但官方 API 有严格的速率限制(通常每个应用每天约 10 万次请求),且只能访问已授权用户自己的数据,无法用于大规模公开数据采集或搜索结果抓取。

Pinterest 内部 Resource API 的工作原理

Pinterest 前端页面并不是通过传统的 REST API 加载数据的。它使用一套内部 Resource API,所有数据请求都通过统一的端点模式进行:

GET https://www.pinterest.com/resource/{ResourceName}/get/
    ?source_url={url_encoded_page_url}
    &data={url_encoded_json_params}

常见的 Resource 端点包括:

Resource 名称用途关键参数
PinResource获取单个图钉详情id, field_set_key
BoardFeedResource获取看板中的图钉列表board_id, page_size, bookmarks
SearchResource搜索图钉/看板query, scope, page_size
UserResource获取用户公开资料username

这些请求需要特定的 HTTP 头才能正常返回数据:

  • X-Pinterest-PWS-Handler:标识前端处理模块,如 www/[username]/[board].js
  • X-APP-VERSION:前端应用版本号,如 abcd123,需与当前部署版本匹配
  • csrftoken:CSRF 令牌,通常从首次访问的 Cookie 中获取
  • User-Agent:必须使用真实浏览器 UA,否则可能被直接拦截

source_url 参数是当前页面的 URL 路径(如 /search/pins/?q=coffee),data 参数是一个 URL 编码的 JSON 对象,包含分页游标(bookmarks)、查询条件和字段配置。

反爬机制与代理策略

Pinterest 使用多层反爬机制来保护其平台:

  • 每 IP 速率限制:同一 IP 在短时间内发送过多请求会触发 429 状态码或临时封禁。根据实测,单 IP 每分钟请求超过 60-100 次即可能触发限制。
  • Bot 评分:Pinterest 会根据请求头、TLS 指纹、行为模式和 IP 信誉对每个请求进行评分。数据中心 IP 通常会被标记为高风险。
  • 本地化搜索:搜索结果和推荐内容基于请求来源的地理位置进行个性化。从日本 IP 搜索 "coffee" 返回的结果与美国 IP 截然不同。

这就是为什么 轮换住宅代理 + 地理定位 对 Pinterest 抓取至关重要。住宅代理使用真实 ISP 分配的 IP 地址,具有较低的 bot 风险评分;通过地理定位(如 country-US),你可以确保搜索结果的一致性和可重复性。

ProxyHat 代理配置

使用 ProxyHat 住宅代理,你可以通过用户名参数实现地理定位和会话保持:

  • 地理定位:user-country-US:pass — 强制使用美国 IP
  • 城市级定位:user-country-US-city-new_york:pass — 精确到城市
  • 粘性会话:user-session-abc123:pass — 在同一会话中保持相同 IP

更多代理位置请查看 ProxyHat 可用地区列表

实战:Python 抓取看板图钉

以下示例展示如何使用 Python requests 通过 ProxyHat 住宅代理分页抓取 Pinterest 看板中的公开图钉:

import requests
import json
import time
from urllib.parse import quote

# ProxyHat 住宅代理配置
proxy_url = "http://user-country-US-session-pinterest01:YOUR_PASSWORD@gate.proxyhat.com:8080"
proxies = {"http": proxy_url, "https": proxy_url}

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
    "Accept": "application/json",
    "Accept-Language": "en-US,en;q=0.9",
    "X-Pinterest-PWS-Handler": "www/[username]/[board].js",
    "X-APP-VERSION": "abcd123",
}

def fetch_board_pins(board_slug, page_size=25, max_pages=10):
    """分页抓取公开看板的图钉列表"""
    all_pins = []
    bookmarks = None
    
    for page in range(max_pages):
        data_params = {
            "options": {
                "board_slug": board_slug,
                "page_size": page_size,
                "current_url": f"/{board_slug}/",
            },
            "context": {}
        }
        if bookmarks:
            data_params["options"]["bookmarks"] = bookmarks
        
        source_url = quote(f"/{board_slug}/", safe="")
        data = quote(json.dumps(data_params), safe="")
        
        url = f"https://www.pinterest.com/resource/BoardFeedResource/get/?source_url={source_url}&data={data}"
        
        try:
            resp = requests.get(url, headers=headers, proxies=proxies, timeout=15)
            if resp.status_code == 429:
                print(f"Rate limited on page {page}, backing off...")
                time.sleep(30)
                continue
            
            result = resp.json()
            pins = result.get("resource_response", {}).get("data", [])
            bookmarks = result.get("resource_response", {}).get("bookmark")
            
            for pin in pins:
                all_pins.append({
                    "id": pin.get("id"),
                    "title": pin.get("title") or pin.get("grid_title"),
                    "image_url": pin.get("images", {}).get("orig", {}).get("url"),
                    "link": pin.get("link"),
                })
            
            if not bookmarks or len(pins) < page_size:
                break
                
            time.sleep(2)  # 请求间隔,避免触发速率限制
        except Exception as e:
            print(f"Error on page {page}: {e}")
            break
    
    return all_pins

# 使用示例
pins = fetch_board_pins("username/board-name", page_size=25, max_pages=10)
print(f"共抓取 {len(pins)} 个图钉")
for pin in pins[:3]:
    print(json.dumps(pin, indent=2, ensure_ascii=False))

上述代码通过 bookmarks 游标实现分页,每次请求携带上一次返回的游标以获取下一页数据。粘性会话(session-pinterest01)确保 csrftoken 在请求间保持一致,避免因 IP 切换导致的 CSRF 验证失败。

实战:Node.js 抓取搜索结果

以下 Node.js 示例通过 ProxyHat HTTP 网关(端口 8080)抓取 Pinterest 搜索结果:

const axios = require("axios");

const proxyConfig = {
  proxy: {
    protocol: "http",
    host: "gate.proxyhat.com",
    port: 8080,
    auth: {
      username: "user-country-US-session-search01",
      password: "YOUR_PASSWORD",
    },
  },
};

const headers = {
  "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
  "Accept": "application/json",
  "X-Pinterest-PWS-Handler": "www/search/[scope].js",
  "X-APP-VERSION": "abcd123",
};

async function searchPins(query, pageSize = 25) {
  const data = JSON.stringify({
    options: {
      query: query,
      scope: "pins",
      page_size: pageSize,
    },
    context: {},
  });

  const sourceUrl = encodeURIComponent(`/search/pins/?q=${query}`);
  const dataParam = encodeURIComponent(data);

  const url = `https://www.pinterest.com/resource/SearchResource/get/?source_url=${sourceUrl}&data=${dataParam}`;

  try {
    const response = await axios.get(url, {
      headers,
      proxy: proxyConfig.proxy,
      timeout: 15000,
    });

    const results = response.data.resource_response?.data || [];
    return results.map((pin) => ({
      id: pin.id,
      title: pin.title || pin.grid_title,
      image: pin.images?.orig?.url,
      link: pin.link,
    }));
  } catch (error) {
    console.error("Search failed:", error.response?.status, error.message);
    return [];
  }
}

// 使用示例
searchPins("minimalist home decor").then((pins) => {
  console.log(`找到 ${pins.length} 个图钉`);
  pins.slice(0, 3).forEach((p) => console.log(JSON.stringify(p, null, 2)));
});

分页、会话管理与指纹防护

游标分页(Bookmark Pagination)

Pinterest 的 Resource API 不使用传统的页码分页,而是使用 bookmarks 游标。每次请求返回的 bookmark 字段是一个 base64 编码的字符串,包含下一次请求的偏移信息。关键点:

  • 第一次请求不携带 bookmarks 参数
  • 后续请求将上一次返回的 bookmark 放入 options.bookmarks 数组
  • 当返回空 bookmark 或空数据时表示已到末尾

粘性会话与 CSRF 连续性

由于 Pinterest 依赖 csrftoken 进行请求验证,频繁切换 IP 会导致 Cookie 失效。使用 ProxyHat 的 session- 参数可以在一定时间内保持同一出口 IP,确保 CSRF 令牌在整个采集过程中有效:

# 同一会话保持相同 IP
http://user-country-US-session-myboard001:pass@gate.proxyhat.com:8080

请求节奏与 User-Agent 卫生

即使使用住宅代理,也需要模拟真实用户行为:

  • 请求间隔:每次请求间隔 2-5 秒,加入随机抖动
  • User-Agent:使用主流浏览器的真实 UA,避免使用已知爬虫 UA(如 python-requests/2.x
  • Accept-Language:与代理地理位置匹配,如美国 IP 使用 en-US,en;q=0.9
  • 并发控制:单会话并发不超过 2-3 个请求,多会话可提高总吞吐量

更多代理配置选项请参考 ProxyHat 官方文档

伦理抓取与官方 API 的选择

数据采集不是法外之地。在构建 Pinterest 数据管道时,请遵循以下原则:

  • 只采集公开、非个人数据:图钉的标题、图片 URL、链接和描述属于公开内容。但用户的行为数据(如点击历史、保存记录)属于个人信息,受 GDPR 保护。
  • 遵守 robots.txt:Pinterest 的 robots.txt 文件定义了允许和禁止爬取的路径。在开始之前请检查 https://www.pinterest.com/robots.txt
  • 控制请求频率:不要对 Pinterest 服务器造成过大负担。合理的请求速率不仅符合道德规范,也能提高采集的长期稳定性。
  • 生产环境优先使用官方 API:如果你的应用需要长期、稳定的数据访问,请评估 Pinterest API v5 是否满足需求。官方 API 提供稳定的 SLA、明确的速率限制和合规保障。

对于需要大规模公开数据采集的场景(如趋势分析、视觉内容数据集构建),代理辅助的网页抓取仍然是必要的补充手段。了解更多代理应用场景请访问 网页抓取用例SERP 追踪用例

关键要点总结

  • 公开数据优先:只抓取无需登录即可访问的公开图钉、看板和搜索结果,避免触碰登录墙后的个人数据。
  • 理解 Resource API:Pinterest 使用内部 Resource API(如 BoardFeedResourceSearchResource),需要正确的请求头和 URL 编码的 JSON 数据参数。
  • 住宅代理 + 地理定位:使用 ProxyHat 住宅代理配合 country-US 参数,确保搜索结果一致性并降低 bot 风险评分。
  • 游标分页 + 粘性会话:使用 bookmarks 游标分页,配合 session- 参数保持 CSRF 令牌连续性。
  • 请求节奏控制:2-5 秒请求间隔,匹配地理位置的 Accept-Language,单会话低并发。
  • 伦理优先:遵守 robots.txt 和服务条款,生产环境优先考虑官方 API v5。

准备好开始抓取 Pinterest 公开数据了吗?查看 ProxyHat 定价方案,选择适合你项目规模的住宅代理套餐。

常见问题

什么是2026年抓取Pinterest图钉和看板?

指的是通过程序化方式采集Pinterest平台上公开可访问的图钉(Pins)和看板(Boards)数据。这通常涉及调用Pinterest的内部Resource API端点(如BoardFeedResource和SearchResource),配合住宅代理进行IP轮换,以获取图钉的ID、标题、图片URL和链接等公开信息。2026年的抓取环境更加复杂,Pinterest加强了反爬机制,需要更精细的请求头管理和代理策略。

为什么抓取Pinterest图钉和看板对代理用户很重要?

Pinterest的搜索结果和推荐内容是基于地理位置进行本地化的,不同国家/地区的IP返回的搜索结果截然不同。此外,Pinterest对单IP有严格的速率限制(约每分钟60-100次请求),超过限制会触发429状态码。使用住宅代理配合地理定位(如country-US)可以确保搜索结果的一致性,同时通过IP轮换避免触发速率限制和bot检测。粘性会话还能保持csrftoken的连续性,确保分页采集不中断。

哪种代理类型最适合抓取Pinterest图钉和看板?

住宅代理是抓取Pinterest的最佳选择。住宅代理使用真实ISP分配的IP地址,具有较低的bot风险评分,不容易被Pinterest的反爬系统识别。数据中心IP通常会被标记为高风险,容易触发封禁。移动代理也可以使用但成本较高。建议选择支持地理定位(country参数)和粘性会话(session参数)的住宅代理服务,如ProxyHat,通过gate.proxyhat.com:8080接入,在用户名中配置country和session参数即可。

如何在抓取Pinterest图钉和看板时避免被封禁?

避免封禁的关键策略包括:使用住宅代理进行IP轮换并配合地理定位;通过session参数保持粘性会话以确保csrftoken连续性;控制请求节奏,每次请求间隔2-5秒并加入随机抖动;使用真实浏览器User-Agent并匹配代理地区的Accept-Language;单会话并发不超过2-3个请求;正确设置X-Pinterest-PWS-Handler和X-APP-VERSION等请求头。遇到429状态码时应立即退避30秒以上。同时务必遵守Pinterest的robots.txt和服务条款。

准备开始了吗?

通过AI过滤访问148多个国家的5000多万个住宅IP。

查看价格住宅代理
← 返回博客