如何下载Instagram视频/图片(一)

78 阅读3分钟

经常可以看到一些网站提供免费的Instagram视频/图片下载服务,自己想开发的时候又没有思路。他们是如何拿到IG帖的视频/图片链接的?!本文以开源项目instagram-video-downloader 为例解析一下。

TL;DR

  1. og:video的meta标签包含资源链接
  2. 匿名graphql请求获取链接
  3. 体验链接: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。

这样我们就可以在不登陆的情况下获取到视频/图片文件链接。如果是非公开的帖子,就需求登录信息了。

image.png