You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化JavaScript代码提取Instagram多视频帖的video src

问题

在Chrome控制台测试JavaScript代码,提取Instagram多视频帖子(含2个以上视频)的video src,目前只能获取DOM已加载的2个src,无法提取其余视频。测试帖子链接:https://www.instagram.com/p/Cz45oeXJhj8/

现有基础代码:

for (const el of document.querySelectorAll('video')) {
  const src = el.getAttribute('src');
  if (src) {
    console.log(src);
  }
}

尝试添加点击“Next”按钮的逻辑来提取更多src,但效果不稳定,无法匹配帖子的视频数量,不确定实现方式是否正确,爬取代码如下:

function extractVideoSources() {
  for (const video of document.querySelectorAll('video')) {
    const src = video.getAttribute('src');
    if (src) {
      console.log(src);
    }
  }
}

function clickNextButtonAndExtract() {
  const nextButton = document.querySelector('button[aria-label="Next"]');
  if (nextButton) {
    nextButton.click();

    setTimeout(() => {
      extractVideoSources();
      clickNextButtonAndExtract(); 
    }, 2000); 
  }
}
clickNextButtonAndExtract();

想知道如何可靠实现该功能,是否需要定位特定容器?


解决方案

核心问题分析

原代码的问题在于:固定2秒延迟无法保证视频DOM完全加载;全局查询所有video元素会重复输出已提取的src;没有判断是否遍历完所有视频,可能陷入无效循环或提前终止。

可靠实现方案

  1. 定位特定容器避免重复抓取:Instagram多视频帖子的媒体内容都在div[role="dialog"]容器内,只查询该容器下的video元素,避免干扰页面其他视频。
  2. 用MutationObserver监听DOM变化:替代固定延迟,确保视频切换完成、DOM更新后再提取src,准确性更高。
  3. 记录已提取的src去重:用Set存储已获取的链接,避免重复输出。
  4. 判断遍历终止条件:当点击Next后回到第一个视频时,说明所有视频已遍历完成,终止流程。

改进后的代码

// 存储已提取的视频src,用于去重
const extractedSources = new Set();
// 存储第一个视频的src,用于判断是否遍历完所有视频
let firstSource = null;

function extractCurrentVideoSource() {
  // 定位当前帖子的视频元素,只抓取目标帖子内的内容
  const videoEl = document.querySelector('div[role="dialog"] video');
  if (!videoEl) return;
  
  const src = videoEl.getAttribute('src');
  if (src && !extractedSources.has(src)) {
    extractedSources.add(src);
    console.log(src);
    // 初始化第一个视频的src标记
    if (!firstSource) firstSource = src;
  }
}

function startExtraction() {
  const nextButton = document.querySelector('button[aria-label="Next"]');
  if (!nextButton) {
    console.log("未找到Next按钮,可能帖子只有一个视频");
    return;
  }

  // 先提取初始显示的第一个视频src
  extractCurrentVideoSource();

  // 监听媒体容器的DOM变化,视频切换时触发提取
  const mediaContainer = document.querySelector('div[role="dialog"] article');
  const observer = new MutationObserver((mutations) => {
    mutations.forEach(() => {
      extractCurrentVideoSource();
      // 检查是否回到第一个视频,判断遍历完成
      const currentVideo = document.querySelector('div[role="dialog"] video');
      if (currentVideo && currentVideo.getAttribute('src') === firstSource) {
        observer.disconnect();
        console.log(`所有视频src提取完成,共提取 ${extractedSources.size} 个`);
        return;
      }
      // 短延迟后点击下一个,避免触发反爬限制
      setTimeout(() => nextButton.click(), 500);
    });
  });

  // 开始监听媒体容器的子元素变化
  observer.observe(mediaContainer, { childList: true, subtree: true });
  // 触发第一次Next点击
  nextButton.click();
}

// 启动提取流程
startExtraction();

代码说明

  • 特定容器定位:通过div[role="dialog"] article锁定目标帖子的媒体区域,确保只抓取当前帖子的视频,不会误抓页面其他视频内容。
  • MutationObserver:实时监听媒体容器的DOM更新,视频切换完成后立即提取src,比固定延迟更适配Instagram的加载节奏。
  • 去重与终止逻辑:用Set存储已提取的链接避免重复,当回到第一个视频时自动终止监听,保证遍历完所有视频。
  • 低延迟点击:500毫秒的点击间隔,既保证流程顺畅,又降低触发Instagram反爬限制的风险。

内容的提问来源于stack exchange,提问作者xyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:52:49