- 后端
【免费下载链接】instagram-private-api
NodeJS Instagram private API SDK. Written in TypeScript.
本篇技术指南围绕 instagram-private-api 项目中SavedFeedResponseMerchant接口展开,讲解这一接口在“已保存帖子(Saved Feed)”响应数据模型中的定位、三个核心字段的语义,以及如何结合SavedFeed数据流与媒体保存接口在实际项目中读取商家信息。读完本文,你将能够在 TypeScript 项目中准确解析 Instagram 购物类已保存内容中的商家数据,并理解其在整个响应类型层级中的位置。
一、接口概览:商家信息的最小数据载体
SavedFeedResponseMerchant是 instagram-private-api 在 TypeScript 中为 Instagram 已保存内容(Saved Feed)响应所定义的一个内嵌接口。它由 typedoc 从 src/responses/saved.feed.response.ts 自动生成文档,位于 docs/modules/responses.md 的响应类型导出体系中,全部响应接口统一由 src/responses/index.ts 通过export * from './saved.feed.response'对外暴露。
从结构上看,该接口非常精简,仅包含 3 个必填字段:
| 属性名 | 类型 | 语义说明 |
|---|---|---|
pk | number | 商家的数字型唯一标识(Instagram 用户 ID) |
username | string | 商家的 Instagram 用户名(不含@前缀) |
profile_pic_url | string | 商家的头像图片 URL,可用于展示商家头像 |
在 TypeScript 中使用时,其结构可直接写作:
interface SavedFeedResponseMerchant { pk: number; username: string; profile_pic_url: string; }字段均为必选且非空,这与接口在 API 响应中的实际地位一致——Instagram 在返回带购物标记(product tag)的已保存媒体时,商家信息通常总是存在,因此接口中没有设置任何可选字段。
二、字段逐个拆解:pk、username、profile_pic_url
2.1 pk:商家的数字标识
pk的类型为number,对应 Instagram 内部使用的用户数字 ID。它与帖子媒体本身的pk(见 SavedFeedResponseMedia,其pk类型为string)不同:媒体的pk是字符串形式的媒体 ID,而商家的pk是纯数字用户 ID。这一点在拼接接口路径或做本地去重、缓存时需要注意类型差异。
2.2 username:商家用户名
username为字符串类型,存储商家的 Instagram 用户名。它是对外展示与跳转的主键之一,通常用于生成商家的主页链接,例如https://instagram.com/{username}形式的拼接(本文不涉及具体外部跳转实现,仅说明其用途)。该字段在 UI 场景下常用于渲染“由 xx 商家提供”之类的文案。
2.3 profile_pic_url:商家头像
profile_pic_url为字符串类型,是商家头像图片的完整 URL。它与普通用户响应中的头像字段一致(可对比 SavedFeedResponseUser 中的profile_pic_url),可用于在列表页、详情页中直接渲染商家的头像缩略图。
这三个字段共同构成了一个“能识别、能展示、能跳转”的最小商家信息集合:pk用于程序化标识,username用于文本展示与跳转,profile_pic_url用于视觉展示。
三、在响应类型树中的位置:从 RootObject 到 Merchant 的完整链路
SavedFeedResponseMerchant并不是孤立存在的,它位于已保存内容响应类型的嵌套结构中。结合 src/responses/saved.feed.response.ts 的完整定义,其层级关系如下:
SavedFeedResponseRootObject └── items: SavedFeedResponseItemsItem[] └── media: SavedFeedResponseMedia └── product_tags?: SavedFeedResponseProduct_tags └── in: SavedFeedResponseInItem[] └── product?: SavedFeedResponseProduct └── merchant: SavedFeedResponseMerchant ← 本文主题对应的源码证据:
- 顶层响应 SavedFeedResponseRootObject:包含
items、num_results、more_available、next_max_id等分页字段; - 每个 item 通过
media字段展开为 SavedFeedResponseMedia,其中product_tags为可选字段(?),仅在内容被标记了购物商品时出现; - 商品标签经由
SavedFeedResponseProduct_tags、SavedFeedResponseInItem到达 SavedFeedResponseProduct; - 商品对象内部通过必填字段
merchant: SavedFeedResponseMerchant引用商家信息(源码第 128 行)。
从字段的可选性可以推断:只有带购物标签(product tag)的已保存帖子才会包含商家数据。因此,读取merchant前应先判断product_tags及其嵌套层是否存在。
3.1 同构接口:TopicalExploreFeedResponseMerchant
值得注意的是,在 Explore 首页动态(Topical Explore)的响应类型中同样存在一个结构完全一致的商家接口:TopicalExploreFeedResponseMerchant,同样由pk、username、profile_pic_url三个字段组成,并由 TopicalExploreFeedResponseProduct 引用。这说明 Instagram 的购物商品数据模型在两个不同的 API 端点间保持一致,也意味着你在 Saved Feed 与 Explore 两个场景中可以复用同一套商家字段解析逻辑。
四、如何拿到这些数据:SavedFeed 数据流与源码印证
商家数据最终由SavedFeed类从 Instagram 的/api/v1/feed/saved/端点拉取。相关实现位于 src/feeds/saved.feed.ts:
async request(): Promise<SavedFeedResponseRootObject> { const { body } = await this.client.request.send({ url: '/api/v1/feed/saved/', qs: { max_id: this.nextMaxId, include_igtv_preview: false, }, }); this.state = body; return body; } async items(): Promise<SavedFeedResponseMedia[]> { const { items } = await this.request(); return items.map(i => i.media); }调用入口由 FeedFactory 提供:
public saved(): SavedFeed { return new SavedFeed(this.client); }实际使用时的读取流程如下(示例代码):
import { IgApiClient } from 'instagram-private-api'; const ig = new IgApiClient(); ig.state.generateDevice('your_seed'); await ig.account.login('username', 'password'); const savedFeed = ig.feed.saved(); const savedItems = await savedFeed.items(); // SavedFeedResponseMedia[] for (const media of savedItems) { // 先判断是否为购物内容 if (media.product_tags) { for (const tagItem of media.product_tags.in) { const product = tagItem.product; if (product) { const merchant: SavedFeedResponseMerchant = product.merchant; console.log({ pk: merchant.pk, username: merchant.username, profilePicUrl: merchant.profile_pic_url, }); } } } }SavedFeed继承自 Feed 基类,天然支持自动分页:items()每次调用都会基于more_available与next_max_id自动请求下一页(见 saved.feed.ts 的 state setter),因此遍历所有已保存购物内容的商家信息只需持续调用items()直到isMoreAvailable()返回false。同时基类提供的observable()/items$与内置重试参数(默认delay: 60000、maxAttempts: 10、jitter: true,见 src/core/feed.ts)可用于对请求频率敏感的批量抓取场景。
4.1 数据闭环:save 与 unsave
商家数据所在的内容本身由媒体仓库的保存/取消保存接口驱动,对应 src/repositories/media.repository.ts:
save(mediaId, collection_ids?):将媒体保存到收藏,可传入collection_ids数组指定目标收藏夹,请求体中包含签名后的_uuid、_uid、_csrftoken、device_id等参数(由client.request.sign()处理);unsave(mediaId):取消保存媒体。
源码注释中给出的使用提示(media.repository.ts 第 680 行)指出可以通过savedFeed.items()[0].media.id拿到已保存媒体的id,进而作为save/unsave的入参——商家信息正是这条“已保存内容”数据链路中的一环。
五、类型安全与边界处理建议
由于product_tags、product均为可选字段,在实际解析时必须处理“非购物内容”的边界情况:
- 先检查
media.product_tags是否存在; - 再检查
tagItem.product是否为空对象(源码中其为可选引用,见 SavedFeedResponseInItem); - 只有
product.merchant一定存在(必填字段),此时可安全读取pk、username、profile_pic_url。
同时建议对profile_pic_url做 URL 合法性与可访问性校验,因为头像 URL 可能随时间失效或需要追加尺寸参数(如?size=l)才能获取更大图。
六、小结
SavedFeedResponseMerchant是 instagram-private-api 已保存内容响应中描述购物商家的核心接口,仅三个字段却贯穿了“已保存帖子 → 购物标签 → 商品 → 商家”的完整数据链路。本文既覆盖了其字段语义与接口层级,也结合 SavedFeed 的分页实现与 media.repository.ts 的保存接口给出了实战读取方案。对于同时使用 Explore 购物场景的开发者,TopicalExploreFeedResponseMerchant 提供了完全一致的数据结构,可复用同一套解析逻辑。
- 后端
【免费下载链接】instagram-private-api
NodeJS Instagram private API SDK. Written in TypeScript.
相关推荐
instagram-private-api 响应类型解析:HighlightsRepositoryHighlightsTrayResponseThumbnails 的字段含义与实战用法
instagram private api 响应类型解析:HighlightsRepositoryHighlightsTrayResponseThumbnail
后端instagram-private-api 响应接口解析:DirectThreadRepositoryUpdateTitleResponseTextAttributesItem 字段详解
instagram private api 响应接口解析:DirectThreadRepositoryUpdateTitleResponseTextAttrib
后端instagram-private-api 响应类型详解:DirectThreadRepositoryApproveParticipantRequestResponseUser 接口字段与审批入群流程
instagram private api 响应类型详解:DirectThreadRepositoryApproveParticipantRequestResp
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考