Pinterest拥有超过4.5亿月活用户,是全球最大的视觉内容发现平台之一。对于构建趋势数据集、竞品分析管道和AI训练语料的开发者来说,Pinterest的Pins和Boards数据具有极高价值。但要在2026年高效抓取Pinterest Pins和Boards,你需要理解其内部API结构、反爬机制以及代理轮换策略。本文将逐一拆解这些技术要点。
法律提示:在抓取任何平台数据前,请务必阅读Pinterest的服务条款。在美国,《计算机欺诈和滥用法》(CFAA)可能适用于未授权访问行为;在欧盟,GDPR对个人数据处理有严格要求。本文仅讨论公开可访问的非个人数据采集,不涉及登录墙后内容。如果你的项目用于商业生产环境,应优先考虑Pinterest官方API v5。
2026年Pinterest Pins和Boards抓取:技术背景
Pinterest的数据获取可以分为三个层次:公开页面、内部Resource API和官方API v5。理解三者的区别是成功抓取的基础。
公开数据面 vs 登录墙数据
Pinterest的公开数据面包括:
- Pin详情页(
/pin/{id}/)— 包含图片、标题、描述和外部链接 - Board页面(
/{username}/{board_slug}/)— 展示该画板下的Pins列表 - 搜索结果页(
/search/pins/?q={query})— 按关键词返回相关Pins - 用户公开Profile页 — 展示公开Boards和Pins
而登录墙后的数据包括:个性化首页推荐流、私密Board内容、关注流和私信。这些内容需要用户登录态才能访问,抓取它们不仅技术上更复杂,法律风险也显著更高。本文不涉及此类数据的采集。
官方Pinterest API v5的局限性
Pinterest提供了官方API v5,但它的功能范围对数据采集者来说相当有限:
- 主要面向广告主和商家,侧重商业账户管理和广告投放
- 无法批量搜索公开Pins或浏览任意用户的Board
- 速率限制严格,通常每个token约1000请求/天
- 需要OAuth授权流程,不适合大规模无登录态数据采集
因此,对于需要大规模公开Pin和Board数据的开发者,理解Pinterest的内部Resource API是必要的补充手段。
Pinterest内部Resource API详解
Pinterest的前端通过一系列内部端点加载数据,这些端点统称为Resource API。它们并非官方公开API,而是Web应用自身使用的JSON数据接口。主要端点包括:
| 端点 | 用途 | 关键参数 |
|---|---|---|
/resource/PinResource/get/ | 获取单个Pin详情 | id, field_set_key |
/resource/BoardFeedResource/get/ | 获取Board下的Pin列表 | board_id, page_size, bookmarks |
/resource/SearchResource/get/ | 搜索Pins | query, scope, bookmarks |
/resource/BoardResource/get/ | 获取Board元数据 | board_id |
这些端点通过?source_url=参数传递路径信息,并使用URL编码的JSON作为data参数。例如,获取Board Feed的请求格式为:
GET /resource/BoardFeedResource/get/?source_url=%2Fusername%2Fboard-slug%2F&data=%7B%22board_id%22%3A%22123456789%22%2C%22page_size%22%3A25%2C%22bookmarks%22%3A%5B%22%22%5D%7D关键请求头包括:
- X-Pinterest-PWS-Handler:标识前端处理模块(如
www/[username]/[slug].js) - X-APP-VERSION:前端应用版本号,需与当前Web版本匹配,通常可从页面HTML的
<meta>标签或JS bundle中提取 - csrftoken:CSRF令牌,从首次请求的响应Cookie中获取
- User-Agent:需使用真实浏览器UA字符串
这些头部值可以通过首次访问目标页面时从响应Cookie和HTML中提取。Pinterest偶尔会更新X-APP-VERSION,因此建议动态获取而非硬编码。
反爬机制与代理策略
Pinterest实施了多层反爬措施,主要包括:
- 每IP速率限制:同一IP短时间内请求过多会触发HTTP 429或302重定向到验证页
- Bot评分:基于请求模式、TLS指纹和行为特征进行评分,低分IP会被静默降级或封锁
- 地理定位:搜索结果和推荐流按用户地理位置个性化,不同国家IP获取的数据差异显著
- Cookie验证:csrftoken与会话Cookie绑定,异常IP切换会触发验证
由于Pinterest的搜索和推荐内容是地理本地化的,使用数据中心IP或单一地区的代理会导致数据偏差。例如,从日本IP搜索"summer fashion"和从美国IP搜索同一关键词,返回结果截然不同。这意味着如果你的目标市场是美国,必须使用美国出口IP才能获取准确的本地化数据。
因此,轮换住宅代理是Pinterest抓取的最佳选择:
- 住宅IP具有真实ISP归属,不易被Bot评分系统标记
- 按国家定位(如
-country-US)确保获取目标地区的本地化数据 - IP轮换分散请求,避免单IP触发速率限制
对比不同代理类型在Pinterest场景下的表现:
| 代理类型 | Bot检测风险 | 地理定位精度 | 并发能力 | 推荐场景 |
|---|---|---|---|---|
| 数据中心代理 | 高 | 有限 | 高 | 不推荐 |
| 移动代理 | 低 | 精确 | 中 | 高隐蔽需求 |
| 住宅代理 | 低 | 精确 | 高 | ✅ 最佳选择 |
Python实战:通过ProxyHat抓取BoardFeedResource
以下示例展示如何使用Python和Web Scraping代理分页抓取Pinterest Board的Pin列表。我们使用ProxyHat住宅代理网关,并设置美国地区定位和粘性会话以保持csrftoken连续性。
import requests
import json
import time
# ProxyHat 住宅代理配置
proxy_user = "user-country-US-session-board1"
proxy_pass = "your_password"
proxy_url = f"http://{proxy_user}:{proxy_pass}@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/120.0.0.0 Safari/537.36",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Language": "en-US,en;q=0.9",
"X-Pinterest-PWS-Handler": "www/[username]/[slug].js",
"X-APP-VERSION": "a8c3f4e",
"Referer": "https://www.pinterest.com/username/board-slug/",
}
def fetch_board_feed(board_id, bookmarks=[""], page_size=25):
"""分页获取 Board Feed Pins"""
session = requests.Session()
session.proxies = proxies
session.headers.update(headers)
# 先访问 Board 页面获取 csrftoken Cookie
init_resp = session.get(
"https://www.pinterest.com/username/board-slug/"
)
csrf_token = session.cookies.get("csrftoken", "")
session.headers["X-CSRFToken"] = csrf_token
data = json.dumps({
"board_id": board_id,
"page_size": page_size,
"bookmarks": bookmarks,
})
params = {
"source_url": "/username/board-slug/",
"data": data,
}
url = "https://www.pinterest.com/resource/BoardFeedResource/get/"
resp = session.get(url, params=params)
if resp.status_code == 200:
result = resp.json()
pins = result.get("resource_response", {}).get("data", [])
next_bookmarks = result.get(
"resource_response", {}).get("bookmark", [""])
for pin in pins[:5]:
print({
"id": pin.get("id"),
"title": pin.get("grid_title", ""),
"image_url": pin.get("images", {})
.get("orig", {}).get("url", ""),
"link": pin.get("link", ""),
})
return next_bookmarks
elif resp.status_code == 429:
print("Rate limited, backing off...")
time.sleep(10)
return fetch_board_feed(board_id, bookmarks, page_size)
else:
print(f"Error: {resp.status_code}")
return None
# 使用示例
next_bm = fetch_board_feed("123456789")
if next_bm and next_bm[0] and next_bm[0] != "-end-":
time.sleep(3)
fetch_board_feed("123456789", bookmarks=next_bm)
上述代码的核心要点:
- 使用
user-country-US-session-board1用户名格式,实现美国地区定位和粘性会话 - 先访问Board页面获取csrftoken Cookie,再请求Resource API
- 解析返回的
bookmark字段进行游标分页 - 每个Pin对象包含
id、grid_title、images.orig.url和link等字段 - 遇到429时执行退避重试
Node.js实战:通过HTTP网关抓取SearchResource
以下Node.js示例展示通过ProxyHat HTTP网关(端口8080)抓取Pinterest搜索结果:
const axios = require("axios");
const HttpsProxyAgent = require("https-proxy-agent");
const proxyUser = "user-country-US-session-search1";
const proxyPass = "your_password";
const proxyUrl = `http://${proxyUser}:${proxyPass}@gate.proxyhat.com:8080`;
const agent = new HttpsProxyAgent(proxyUrl);
const baseHeaders = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) " +
"Chrome/120.0.0.0 Safari/537.36",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Language": "en-US,en;q=0.9",
"X-Pinterest-PWS-Handler": "www/search/[scope].js",
"X-APP-VERSION": "a8c3f4e",
};
async function searchPins(query, bookmarks = []) {
const searchUrl = `https://www.pinterest.com/search/pins/?q=${encodeURIComponent(query)}`;
// 先获取 csrftoken
const initResp = await axios.get(searchUrl, {
httpsAgent: agent,
headers: { ...baseHeaders, Referer: searchUrl },
});
const cookies = initResp.headers["set-cookie"] || [];
const csrfToken = cookies
.find(c => c.startsWith("csrftoken="))
?.match(/csrftoken=([^;]+)/)?.[1] || "";
const data = JSON.stringify({
query: query,
scope: "pins",
page_size: 25,
bookmarks: bookmarks,
});
const params = new URLSearchParams({
source_url: `/search/pins/?q=${encodeURIComponent(query)}`,
data: data,
});
const resp = await axios.get(
"https://www.pinterest.com/resource/SearchResource/get/",
{
httpsAgent: agent,
headers: {
...baseHeaders,
"X-CSRFToken": csrfToken,
Referer: searchUrl,
},
params: params,
}
);
const results = resp.data.resource_response.data;
const nextBookmark = resp.data.resource_response.bookmark;
results.slice(0, 5).forEach(pin => {
console.log({
id: pin.id,
title: pin.grid_title || "",
image: pin.images?.orig?.url || "",
link: pin.link || "",
});
});
return nextBookmark && nextBookmark !== "-end-"
? [nextBookmark] : null;
}
searchPins("summer fashion").then(bm => {
if (bm) setTimeout(() => searchPins("summer fashion", bm), 3000);
});
分页、会话与指纹管理
Bookmark游标分页机制
Pinterest使用bookmarks数组进行游标分页,而非传统的offset/limit。每次请求返回的bookmark字符串作为下次请求的bookmarks参数。当返回的bookmark为["-end-"]时,表示已到达末尾。这种分页方式意味着你无法跳页,必须顺序获取。
粘性会话与csrftoken连续性
由于csrftoken与IP会话绑定,在同一批请求中应使用粘性会话(如-session-board1),确保同一出口IP处理整个分页流程。如果中途切换IP,会导致csrftoken失效,需要重新初始化会话。建议的会话策略:
- 每个Board或搜索任务使用独立session ID
- 一个session处理10-20个分页请求后轮换
- 轮换时重新获取csrftoken
- 不同任务使用不同session ID避免关联
请求节奏控制
合理的请求间隔是避免触发反爬的关键。根据实践经验,推荐以下节奏:
- 单个IP:每请求间隔2-5秒,使用随机抖动避免固定模式
- 并发IP:不超过10-20个并发会话
- 使用指数退避处理429响应(初始10秒,每次翻倍)
- 每日单IP请求量控制在500-1000以内
User-Agent与指纹管理
保持一致的浏览器指纹至关重要。Pinterest的反爬系统会检查请求头的一致性:
- 使用主流浏览器的最新UA字符串(Chrome、Firefox等)
- 确保
Accept、Accept-Language、Sec-CH-UA等头部与UA匹配 - 不要在同一会话中切换UA
- 考虑使用完整的HTTP头部集,参考MDN HTTP Headers文档
- TLS指纹也是Bot评分因素之一,高级场景可考虑使用支持TLS指纹模拟的HTTP库
ProxyHat代理配置与最佳实践
在Pinterest抓取场景中,住宅代理是明确的最优选择。ProxyHat住宅代理支持精确的地理定位和粘性会话,适配Pinterest的本地化内容策略。查看ProxyHat定价方案了解住宅代理套餐详情。
ProxyHat代理配置要点:
- 网关地址:
gate.proxyhat.com:8080(HTTP)或:1080(SOCKS5) - 国家定位:用户名中使用
-country-US、-country-DE等 - 城市定位:
-country-US-city-newyork实现更细粒度的地理控制 - 粘性会话:
-session-{id}保持同一出口IP,适合分页场景 - 查看完整的代理位置列表了解支持的国家和城市
更多代理使用技巧请参考ProxyHat官方文档。对于SERP和搜索结果监控场景,也可参考我们的SERP追踪用例。
合规采集与何时使用官方API
数据采集必须遵循道德和法律底线。以下原则应贯穿你的Pinterest抓取项目。
只采集公开、非个人数据
Pinterest上的Pin数据(图片URL、标题、描述、链接)在用户公开分享时属于公开信息。但应严格避免:
- 采集用户个人信息(邮箱、手机号、物理地址等)
- 抓取登录墙后的私密Board内容
- 将采集数据用于垃圾营销、用户画像或人肉搜索
- 绕过Pinterest的访问控制机制
遵守robots.txt
在抓取前应检查https://www.pinterest.com/robots.txt,遵守其中规定的爬虫访问限制。虽然robots.txt不具法律强制力,但它是平台表达意愿的重要信号,也是合规采集的基本礼仪。
何时应使用官方API而非抓取
以下场景应优先使用Pinterest官方API v5:
- 商业产品集成(如电商同步Pin到店铺)
- 需要写入操作(创建Pin、管理Board)
- 需要用户授权数据(如个人Board管理)
- 生产环境需要稳定SLA和官方支持的场景
而抓取更适合以下场景:
- 大规模公开数据集构建(如趋势分析、视觉内容研究)
- SEO和SERP监控
- 学术研究中的视觉内容分析
- 竞品Board结构和内容研究
关键要点
- Pinterest内部Resource API(PinResource、BoardFeedResource、SearchResource)是获取公开Pin和Board数据的主要途径,需配合正确的请求头(X-Pinterest-PWS-Handler、X-APP-VERSION、csrftoken)
- 住宅代理配合地理定位(
-country-US)是Pinterest抓取的最佳实践,因为搜索结果按地区个性化- 使用粘性会话(
-session-{id})保持csrftoken连续性,避免会话中断导致重新初始化- Bookmark游标分页是Pinterest的标准分页方式,注意
-end-标记表示到达末尾- 请求间隔控制在2-5秒,并发会话不超过20个,每日单IP请求量控制在1000以内
- 只采集公开非个人数据,遵守robots.txt,商业用途优先考虑官方API v5
常见问题
什么是Pinterest Pins和Boards抓取?
Pinterest Pins和Boards抓取是指通过编程方式获取Pinterest平台上公开的Pin(图钉)和Board(画板)数据。Pin包含图片URL、标题、描述和外部链接等信息;Board是用户创建的图钉集合。抓取通常通过Pinterest的内部Resource API端点(如BoardFeedResource和SearchResource)实现,而非官方API v5,因为后者功能有限且速率限制严格。
为什么Pinterest抓取需要使用代理?
Pinterest对同一IP的请求频率有严格限制,短时间内大量请求会触发429错误或验证页面。此外,Pinterest的搜索结果和推荐内容按地理位置个性化,使用单一IP会导致数据偏差。住宅代理提供真实ISP IP,支持地理定位,能有效分散请求并获取本地化数据。数据中心IP容易被Bot评分系统识别和封锁,不推荐用于Pinterest抓取。
哪种代理类型最适合Pinterest抓取?
住宅代理是最佳选择。数据中心IP容易被Pinterest的Bot评分系统识别和封锁;移动代理虽然隐蔽性高但成本较高且并发能力有限。住宅代理兼具低检测风险、精确地理定位和高并发能力,适合Pinterest的本地化内容和反爬机制。ProxyHat住宅代理通过-country-US等参数支持精确地理定位,通过-session-{id}支持粘性会话。
如何避免Pinterest抓取时的IP封锁?
关键策略包括:使用轮换住宅代理分散请求来源;使用粘性会话(-session-{id})保持csrftoken连续性;控制请求间隔在2-5秒并加入随机抖动;限制并发会话数在20个以内;使用真实浏览器User-Agent并保持头部一致性;使用指数退避处理429响应;每个session处理10-20个请求后轮换IP和会话。
Pinterest官方API v5能否替代抓取?
不能完全替代。API v5主要面向广告主和商家,侧重商业账户管理,无法批量搜索公开Pins或浏览任意Board,且速率限制严格(约1000请求/天)。对于大规模公开数据采集、趋势分析和竞品研究,抓取仍是更可行的方案。但对于商业产品集成和写入操作,应使用官方API以确保合规性和稳定性。






