经常可以看到一些网站提供免费的Instagram视频/图片下载服务,自己想开发的时候又没有思路。他们是如何拿到IG帖的视频/图片链接的?!本文以开源项目instagram-video-downloader 为例解析一下。
TL;DR
- og:video的meta标签包含资源链接
- 匿名graphql请求获取链接
- 体验链接:insta-j.vercel.app/
解析HTML,获取下载链接
Instagram的分享链接形如https://www.instagram.com/p/<shortcode>
。直接通过网络请求获取的HTML文档中包含了社交媒体分享的meta,如<meta property="og:image">
和<meta property="og:video">
,其中content包含的帖子视频/图片的url。
因为只是预览图片,且视频meta[property='og:video']
标签似乎已经不再提供。所以这种方法不再推荐。这里推荐cheeriojs解析HTML文档,快速获取想要的元素
匿名graphql请求
还记得分享链接都带有一个shortcode吗,Instagram支持graphql请求获取相关帖子的信息。
请求类型:POST
请求url:https://www.instagram.com/api/graphql
不知道从哪里搞来的请求头:
{
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Content-Type": "application/x-www-form-urlencoded",
"X-FB-Friendly-Name": "PolarisPostActionLoadPostQueryQuery",
"X-CSRFToken": "RVDUooU5MYsBbS1CNN3CzVAuEP8oHB52",
"X-IG-App-ID": "1217981644879628",
"X-FB-LSD": "AVqbxe3J_YA",
"X-ASBD-ID": "129477",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent":
"Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-G973U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/14.2 Chrome/87.0.4280.141 Mobile Safari/537.36",
}
不明意义的请求体:
{
av: "0",
__d: "www",
__user: "0",
__a: "1",
__req: "3",
__hs: "19624.HYP:instagram_web_pkg.2.1..0.0",
dpr: "3",
__ccg: "UNKNOWN",
__rev: "1008824440",
__s: "xf44ne:zhh75g:xr51e7",
__hsi: "7282217488877343271",
__dyn:
"7xeUmwlEnwn8K2WnFw9-2i5U4e0yoW3q32360CEbo1nEhw2nVE4W0om78b87C0yE5ufz81s8hwGwQwoEcE7O2l0Fwqo31w9a9x-0z8-U2zxe2GewGwso88cobEaU2eUlwhEe87q7-0iK2S3qazo7u1xwIw8O321LwTwKG1pg661pwr86C1mwraCg",
__csr:
"gZ3yFmJkillQvV6ybimnG8AmhqujGbLADgjyEOWz49z9XDlAXBJpC7Wy-vQTSvUGWGh5u8KibG44dBiigrgjDxGjU0150Q0848azk48N09C02IR0go4SaR70r8owyg9pU0V23hwiA0LQczA48S0f-x-27o05NG0fkw",
__comet_req: "7",
lsd: "AVqbxe3J_YA",
jazoest: "2957",
__spin_r: "1008824440",
__spin_b: "trunk",
__spin_t: "1695523385",
fb_api_caller_class: "RelayModern",
fb_api_req_friendly_name: "PolarisPostActionLoadPostQueryQuery",
variables: JSON.stringify({
shortcode: shortcode,
fetch_comment_count: "null",
fetch_related_profile_media_count: "null",
parent_comment_count: "null",
child_comment_count: "null",
fetch_like_count: "null",
fetch_tagged_user_count: "null",
fetch_preview_comment_count: "null",
has_threaded_comments: "false",
hoisted_comment_id: "null",
hoisted_reply_id: "null",
}),
server_timestamps: "true",
doc_id: "10015901848480474",
}
请求体需要转换成query string字符串,可以使用node:querystring.stringify()
或URLSearchParams.stringify()
媒体相关的信息在响应的data.xdt_shortcode_media
中。可以找到图文的url。
这样我们就可以在不登陆的情况下获取到视频/图片文件链接。如果是非公开的帖子,就需求登录信息了。