06 August 2026

How to fetch instagram posts data?

Fetch Instagram posts data by pasting this code in browser console.


(() => {

/* ============================================================
INSTAGRAM PUBLIC PROFILE RESEARCH COLLECTOR
WITH PREVIOUS CSV CONTINUATION
============================================================ */

if (window.igResearchCollectorV3Continue) {
console.log("Instagram collector is already loaded.");
return;
}


/* ============================================================
SETTINGS
SAME STYLE AS ORIGINAL V3
============================================================ */

const SETTINGS = {

// Delay after profile scrolling
scrollDelay: 1800,

// Stop after this many scroll rounds with no new posts
noNewScrollLimit: 7,

// Safety limit
maxScrollRounds: 400,

// Wait after loading individual post
postLoadDelay: 2500,

// Delay between posts
betweenPostsDelay: 2000,

// 0 = process every discovered post
maxPosts: 0
};


/* ============================================================
CSV COLUMNS
SAME DETAILED EXPORT STRUCTURE
============================================================ */

const COLUMNS = [

"row_number",

"profile_username",
"profile_name",
"profile_url",
"profile_description",

"post_shortcode",
"post_url",
"post_type",

"posted_date",
"posted_datetime",
"displayed_date",

"post_caption",

"caption_word_count",
"caption_character_count",
"caption_sentence_count",

"image_alt_text",

"representative_image_url",

"hashtags",
"hashtag_count",

"mentions",
"mention_count",

"visible_likes",
"visible_comments",
"visible_views",

"location",

"raw_visible_post_text",
"raw_meta_description",

"collection_status",
"collection_error",
"collected_at"
];


/* ============================================================
STATE
============================================================ */

const postUrls =
new Map();


/*
* Only NEW records collected during this browser session
* are stored here.
*
* Previous CSV remains as one raw text string.
*/

const results =
[];


/*
* URLs already contained in previous CSV
* plus URLs collected during this session.
*/

const processedUrls =
new Set();


let previousCsvText =
"";


let previousCsvFileName =
"";


let previousRowCount =
0;


let nextRowNumber =
1;


let running =
false;


let stopRequested =
false;


let processingWindow =
null;


/* ============================================================
BASIC HELPERS
============================================================ */

const sleep = ms =>
new Promise(
resolve =>
setTimeout(
resolve,
ms
)
);


const cleanText = (value = "") =>
String(value)
.replace(
/\u00a0/g,
" "
)
.replace(
/\s+/g,
" "
)
.trim();


const unique = values =>
[
...new Set(
values.filter(Boolean)
)
];


function getProfileUsername() {

return location.pathname
.split("/")
.filter(Boolean)[0] || "";
}


function getShortcode(url) {

try {

const parts =
new URL(
url,
location.origin
)
.pathname
.split("/")
.filter(Boolean);


if (
parts[0] === "p" ||
parts[0] === "reel" ||
parts[0] === "reels"
) {

return (
parts[1] ||
""
);
}


const index =
parts.findIndex(
part =>
part === "p" ||
part === "reel" ||
part === "reels"
);


if (
index >= 0 &&
parts[index + 1]
) {

return (
parts[
index + 1
]
);
}

} catch (e) {}


return "";
}


function getMeta(
doc,
property
) {

return (
doc.querySelector(
`meta[property="${property}"]`
)?.content ||
""
);
}


/* ============================================================
FLOATING PANEL STATUS
============================================================ */

function setStatus(message) {

console.log(
"[Instagram Collector]",
message
);


const element =
document.getElementById(
"ig-v3c-status"
);


if (element) {

element.textContent =
message;
}
}


function updateCounters() {

const found =
document.getElementById(
"ig-v3c-found"
);


const processed =
document.getElementById(
"ig-v3c-processed"
);


const imported =
document.getElementById(
"ig-v3c-imported"
);


if (found) {

found.textContent =
`Posts found: ${postUrls.size}`;
}


if (processed) {

processed.textContent =
`Total records: ${
previousRowCount +
results.length
} | New this run: ${
results.length
}`;
}


if (imported) {

imported.textContent =
previousCsvText
? `Previous CSV: ${previousRowCount} rows loaded`
: "Previous CSV: not loaded";
}
}


/* ============================================================
PROFILE INFORMATION
============================================================ */

function getMainProfileInfo() {

const username =
getProfileUsername();


return {

profile_username:
username,

profile_url:
username
? `${location.origin}/${username}/`
: "",

profile_name:
cleanText(
document.querySelector(
"header h2"
)?.innerText ||

document.querySelector(
"header h1"
)?.innerText ||

""
),

profile_description:
cleanText(
getMeta(
document,
"og:description"
)
),

profile_image_url:
getMeta(
document,
"og:image"
)
};
}


const PROFILE =
getMainProfileInfo();


/* ============================================================
CSV PARSER

Handles:
commas
quotes
escaped quotes
multiline caption fields
============================================================ */

function parseCSV(text) {

const rows =
[];


let row =
[];


let field =
"";


let insideQuotes =
false;


for (
let i = 0;
i < text.length;
i++
) {

const char =
text[i];


if (
insideQuotes
) {

if (
char === '"'
) {

if (
text[i + 1] === '"'
) {

field +=
'"';


i++;

} else {

insideQuotes =
false;
}

} else {

field +=
char;
}


continue;
}


if (
char === '"'
) {

insideQuotes =
true;


continue;
}


if (
char === ","
) {

row.push(
field
);


field =
"";


continue;
}


if (
char === "\n"
) {

row.push(
field
);


rows.push(
row
);


row =
[];


field =
"";


continue;
}


if (
char === "\r"
) {

continue;
}


field +=
char;
}


/*
* Final field / row.
*/

if (
field.length ||
row.length
) {

row.push(
field
);


rows.push(
row
);
}


return rows;
}


/* ============================================================
LOAD PREVIOUS CSV
============================================================ */

function loadPreviousCSV() {

if (
running
) {

alert(
"Stop the collector before loading a previous CSV."
);


return;
}


const input =
document.createElement(
"input"
);


input.type =
"file";


input.accept =
".csv,text/csv";


input.style.display =
"none";


input.onchange =
async () => {

const file =
input.files?.[0];


input.remove();


if (!file) {

return;
}


try {

setStatus(
"Reading previous CSV..."
);


const text =
await file.text();


const cleanCsv =
text.replace(
/^\uFEFF/,
""
);


const rows =
parseCSV(
cleanCsv
);


if (
rows.length <
2
) {

throw new Error(
"CSV does not contain post records."
);
}


const headers =
rows[0]
.map(
value =>
cleanText(
value
)
);


/*
* Validate that this is the same
* detailed-post-data CSV format.
*/

for (
let index = 0;
index <
COLUMNS.length;
index++
) {

if (
headers[index] !==
COLUMNS[index]
) {

throw new Error(
`CSV column mismatch at column ${index + 1}. Expected "${COLUMNS[index]}", found "${headers[index] || ""}".`
);
}
}


const postUrlIndex =
headers.indexOf(
"post_url"
);


const rowNumberIndex =
headers.indexOf(
"row_number"
);


if (
postUrlIndex < 0 ||
rowNumberIndex < 0
) {

throw new Error(
"CSV is missing post_url or row_number."
);
}


/*
* Loading a previous CSV starts
* continuation mode fresh.
*/

postUrls.clear();


processedUrls.clear();


results.length =
0;


let imported =
0;


let highestRow =
0;


for (
let index = 1;
index < rows.length;
index++
) {

const row =
rows[index];


/*
* Ignore completely blank final row.
*/

if (
!row.some(
value =>
String(
value ?? ""
).trim()
)
) {

continue;
}


const postUrl =
cleanText(
row[
postUrlIndex
] || ""
);


const rowNumber =
Number(
row[
rowNumberIndex
]
);


if (
postUrl
) {

processedUrls.add(
postUrl
);
}


if (
Number.isFinite(
rowNumber
) &&
rowNumber >
highestRow
) {

highestRow =
rowNumber;
}


imported++;
}


previousCsvText =
cleanCsv
.replace(
/(?:\r?\n)+$/,
""
);


previousCsvFileName =
file.name;


previousRowCount =
imported;


nextRowNumber =
highestRow > 0
? highestRow + 1
: imported + 1;


updateCounters();


setStatus(
`Previous CSV loaded: ${imported} rows. New records will start at row ${nextRowNumber}.`
);


console.log(
`[Instagram Collector] Loaded ${imported} existing rows from ${file.name}.`
);


console.log(
`[Instagram Collector] ${processedUrls.size} existing post URLs will be skipped.`
);


} catch (error) {

console.error(
error
);


alert(
`Could not load CSV:\n\n${
error.message ||
error
}`
);


setStatus(
"Previous CSV could not be loaded."
);
}
};


document.body.appendChild(
input
);


input.click();
}


/* ============================================================
FIND CURRENTLY LOADED POST URLS
ORIGINAL STYLE
============================================================ */

function collectPostUrls() {

let added =
0;


const anchors =
document.querySelectorAll(
'a[href*="/p/"], a[href*="/reel/"]'
);


anchors.forEach(
anchor => {

try {

const url =
new URL(
anchor.href,
location.origin
);


const path =
url.pathname;


if (
!path.includes(
"/p/"
) &&
!path.includes(
"/reel/"
)
) {

return;
}


const cleanUrl =
`${url.origin}${path}`;


if (
!postUrls.has(
cleanUrl
)
) {

postUrls.set(
cleanUrl,
true
);


added++;
}

} catch (e) {}
}
);


updateCounters();


return added;
}


/* ============================================================
AUTO SCROLL PROFILE
ORIGINAL LOGIC
============================================================ */

async function scanProfile() {

setStatus(
"Scanning profile..."
);


collectPostUrls();


let previousCount =
postUrls.size;


let noNewRounds =
0;


for (
let round = 1;
round <=
SETTINGS.maxScrollRounds;
round++
) {

if (
stopRequested
) {

break;
}


window.scrollBy({

top:
Math.floor(
window.innerHeight *
0.85
),

left:
0,

behavior:
"smooth"
});


await sleep(
SETTINGS.scrollDelay
);


collectPostUrls();


const currentCount =
postUrls.size;


if (
currentCount ===
previousCount
) {

noNewRounds++;

} else {

noNewRounds =
0;


previousCount =
currentCount;
}


setStatus(
`Scanning profile: ${currentCount} unique posts found`
);


if (
noNewRounds >=
SETTINGS.noNewScrollLimit
) {

break;
}


if (
SETTINGS.maxPosts >
0 &&
currentCount >=
SETTINGS.maxPosts
) {

break;
}
}


setStatus(
`Profile scan complete: ${postUrls.size} posts found`
);
}


/* ============================================================
WAIT FOR POST PAGE
ORIGINAL V3 LOGIC
============================================================ */

async function waitForPost(win) {

const started =
Date.now();


const timeout =
20000;


while (
Date.now() -
started <
timeout
) {

if (
stopRequested
) {

return false;
}


if (
win.closed
) {

return false;
}


try {

const pathname =
win.location.pathname ||
"";


const bodyText =
cleanText(
win.document.body
?.innerText ||
""
);


if (
pathname.includes(
"/challenge/"
) ||
pathname.includes(
"/accounts/login/"
)
) {

throw new Error(
"Instagram requested login or verification."
);
}


if (
/temporarily blocked|try again later|confirm it's you/i
.test(
bodyText
)
) {

throw new Error(
"Instagram temporarily interrupted the session."
);
}


if (
win.document
.querySelector(
"article"
)
) {

return true;
}

} catch (error) {

if (
/Instagram/i.test(
error.message ||
""
)
) {

throw error;
}
}


await sleep(
500
);
}


return false;
}


/* ============================================================
CAPTION
ORIGINAL EXTRACTION LOGIC
============================================================ */

function extractCaption(
doc,
article
) {

const headings =
[
...article
.querySelectorAll(
"h1"
)
]
.map(
element =>
cleanText(
element.innerText
)
)
.filter(Boolean);


if (
headings.length
) {

return headings.sort(
(
a,
b
) =>
b.length -
a.length
)[0];
}


const description =
cleanText(
getMeta(
doc,
"og:description"
)
);


if (
!description
) {

return "";
}


const quoted =
description.match(
/:\s*["“]([\s\S]*?)["”]\s*$/
);


if (
quoted?.[1]
) {

return cleanText(
quoted[1]
);
}


const colon =
description.indexOf(
":"
);


if (
colon !== -1
) {

return cleanText(
description.substring(
colon + 1
)
)
.replace(
/^["“]|["”]$/g,
""
);
}


return "";
}


/* ============================================================
IMAGE ALT TEXT
============================================================ */

function extractImageAltText(
article
) {

const images =
[
...article
.querySelectorAll(
"img"
)
]
.filter(
img => {

try {

const rect =
img
.getBoundingClientRect();


return (
rect.width >=
180 &&
rect.height >=
180
);

} catch {

return false;
}
}
);


const altTexts =
unique(
images
.map(
img =>
cleanText(
img.alt ||
""
)
)
.filter(Boolean)
);


return altTexts.join(
" | "
);
}


/* ============================================================
REPRESENTATIVE IMAGE
============================================================ */

function extractRepresentativeImage(
doc,
article
) {

const ogImage =
getMeta(
doc,
"og:image"
);


if (
ogImage
) {

return ogImage;
}


const images =
[
...article
.querySelectorAll(
"img"
)
]
.filter(
img => {

try {

const rect =
img
.getBoundingClientRect();


return (
rect.width >=
200 &&
rect.height >=
200
);

} catch {

return false;
}
}
);


return (
images[0]?.currentSrc ||
images[0]?.src ||
""
);
}


/* ============================================================
DATE
============================================================ */

function extractDate(
article
) {

const time =
article.querySelector(
"time[datetime]"
);


const datetime =
time?.getAttribute(
"datetime"
) ||
"";


return {

posted_datetime:
datetime,

posted_date:
datetime
? datetime.substring(
0,
10
)
: "",

displayed_date:
cleanText(
time?.innerText ||
""
)
};
}


/* ============================================================
LOCATION
============================================================ */

function extractLocation(
article
) {

const location =
article.querySelector(
'a[href*="/explore/locations/"]'
);


return cleanText(
location?.innerText ||
""
);
}


/* ============================================================
ENGAGEMENT
============================================================ */

function extractEngagement(
doc,
article
) {

const metaDescription =
cleanText(
getMeta(
doc,
"og:description"
)
);


const visibleText =
cleanText(
article.innerText ||
""
);


let likes =
"";


let comments =
"";


let views =
"";


const likesMatch =
metaDescription.match(
/([\d.,]+(?:\s?[KMB])?)\s+likes?/i
);


if (
likesMatch
) {

likes =
likesMatch[1];
}


const commentsMatch =
metaDescription.match(
/([\d.,]+(?:\s?[KMB])?)\s+comments?/i
);


if (
commentsMatch
) {

comments =
commentsMatch[1];
}


const viewsMatch =
visibleText.match(
/([\d.,]+(?:\s?[KMB])?)\s+views?/i
);


if (
viewsMatch
) {

views =
viewsMatch[1];
}


return {

visible_likes:
likes,

visible_comments:
comments,

visible_views:
views
};
}


/* ============================================================
HASHTAGS / MENTIONS
============================================================ */

function analyzeCaption(
caption
) {

const hashtags =
unique(
caption.match(
/#[\p{L}\p{N}_]+/gu
) ||
[]
);


const mentions =
unique(
caption.match(
/@[\p{L}\p{N}._]+/gu
) ||
[]
);


const words =
caption
.split(
/\s+/
)
.filter(Boolean);


const sentences =
caption
.split(
/[.!?]+/
)
.map(
cleanText
)
.filter(Boolean);


return {

caption_word_count:
words.length,

caption_character_count:
caption.length,

caption_sentence_count:
sentences.length,

hashtags:
hashtags.join(
" | "
),

hashtag_count:
hashtags.length,

mentions:
mentions.join(
" | "
),

mention_count:
mentions.length
};
}


/* ============================================================
POST TYPE
============================================================ */

function detectPostType(
url,
article
) {

if (
url.includes(
"/reel/"
)
) {

return "Reel";
}


if (
article.querySelector(
'svg[aria-label="Next"], svg[aria-label="next"]'
)
) {

return "Carousel";
}


if (
article.querySelector(
"video"
)
) {

return "Video";
}


return "Image";
}


/* ============================================================
ACCOUNT USERNAME FROM POST
============================================================ */

function extractPostUsername(
doc,
article
) {

const ogTitle =
getMeta(
doc,
"og:title"
);


const match =
ogTitle.match(
/@([A-Za-z0-9._]+)/
);


if (
match?.[1]
) {

return match[1];
}


return (
PROFILE.profile_username
);
}


/* ============================================================
PROCESS ONE POST
SAME DETAILED RECORD
============================================================ */

async function processPost(
url,
rowNumber
) {

const record = {

row_number:
rowNumber,


/* PROFILE */

profile_username:
"",

profile_name:
PROFILE.profile_name,

profile_url:
PROFILE.profile_url,

profile_description:
PROFILE.profile_description,

profile_image_url:
PROFILE.profile_image_url,


/* POST */

post_shortcode:
getShortcode(
url
),

post_url:
url,

post_type:
"",


/* DATE */

posted_date:
"",

posted_datetime:
"",

displayed_date:
"",


/* CAPTION */

post_caption:
"",

caption_word_count:
0,

caption_character_count:
0,

caption_sentence_count:
0,


/* IMAGE */

image_alt_text:
"",

representative_image_url:
"",


/* TAGS */

hashtags:
"",

hashtag_count:
0,

mentions:
"",

mention_count:
0,


/* ENGAGEMENT */

visible_likes:
"",

visible_comments:
"",

visible_views:
"",


/* LOCATION */

location:
"",


/* RAW */

raw_visible_post_text:
"",

raw_meta_description:
"",


/* COLLECTION */

collection_status:
"processing",

collection_error:
"",

collected_at:
new Date()
.toISOString()
};


try {

processingWindow.location.href =
url;


const loaded =
await waitForPost(
processingWindow
);


if (
!loaded
) {

throw new Error(
"Post page did not load."
);
}


await sleep(
SETTINGS.postLoadDelay
);


const doc =
processingWindow.document;


const article =
doc.querySelector(
"article"
);


if (
!article
) {

throw new Error(
"Instagram post content was not found."
);
}


/* PROFILE */

const username =
extractPostUsername(
doc,
article
);


record.profile_username =
username;


record.profile_url =
username
? `https://www.instagram.com/${username}/`
: PROFILE.profile_url;


/* POST TYPE */

record.post_type =
detectPostType(
url,
article
);


/* DATE */

const date =
extractDate(
article
);


record.posted_date =
date.posted_date;


record.posted_datetime =
date.posted_datetime;


record.displayed_date =
date.displayed_date;


/* CAPTION */

const caption =
extractCaption(
doc,
article
);


record.post_caption =
caption;


const captionData =
analyzeCaption(
caption
);


record.caption_word_count =
captionData
.caption_word_count;


record.caption_character_count =
captionData
.caption_character_count;


record.caption_sentence_count =
captionData
.caption_sentence_count;


/* IMAGE ALT */

record.image_alt_text =
extractImageAltText(
article
);


/* IMAGE URL */

record.representative_image_url =
extractRepresentativeImage(
doc,
article
);


/* TAGS */

record.hashtags =
captionData.hashtags;


record.hashtag_count =
captionData
.hashtag_count;


record.mentions =
captionData.mentions;


record.mention_count =
captionData
.mention_count;


/* ENGAGEMENT */

const engagement =
extractEngagement(
doc,
article
);


record.visible_likes =
engagement
.visible_likes;


record.visible_comments =
engagement
.visible_comments;


record.visible_views =
engagement
.visible_views;


/* LOCATION */

record.location =
extractLocation(
article
);


/* RAW */

record.raw_visible_post_text =
cleanText(
article.innerText ||
""
);


record.raw_meta_description =
cleanText(
getMeta(
doc,
"og:description"
)
);


record.collection_status =
"success";


} catch (error) {

record.collection_status =
"error";


record.collection_error =
cleanText(
error.message ||
String(error)
);
}


return record;
}


/* ============================================================
PROCESS ONLY POSTS NOT ALREADY IN PREVIOUS CSV
============================================================ */

async function processAllPosts() {

let urls =
[
...postUrls.keys()
];


/*
* IMPORTANT:
* skip everything already contained
* in previous CSV.
*/

urls =
urls.filter(
url =>
!processedUrls.has(
url
)
);


if (
SETTINGS.maxPosts >
0
) {

urls =
urls.slice(
0,
SETTINGS.maxPosts
);
}


if (
!urls.length
) {

setStatus(
"No new posts to process."
);


return;
}


setStatus(
`Starting from row ${nextRowNumber}. ${urls.length} new posts remaining.`
);


for (
let index = 0;
index < urls.length;
index++
) {

if (
stopRequested
) {

break;
}


const url =
urls[index];


setStatus(
`Processing new post ${index + 1} / ${urls.length} | CSV row ${nextRowNumber}`
);


const record =
await processPost(
url,
nextRowNumber
);


results.push(
record
);


/*
* Mark as processed so Start cannot
* collect it again during this session.
*/

processedUrls.add(
url
);


nextRowNumber++;


updateCounters();


/*
* Same safety behavior:
* stop on Instagram interruption.
*/

if (
record.collection_error &&
/verification|temporarily|login|interrupted/i
.test(
record.collection_error
)
) {

stopRequested =
true;


setStatus(
"Instagram interrupted collection. Existing data can still be downloaded."
);


break;
}


await sleep(
SETTINGS.betweenPostsDelay
);
}


if (
!stopRequested
) {

setStatus(
`Finished. ${results.length} new posts added.`
);
}
}


/* ============================================================
CSV EXPORT
PREVIOUS CSV + NEW ROWS
============================================================ */

function escapeCSV(value) {

return (
'"' +
String(
value ?? ""
)
.replace(
/"/g,
'""'
) +
'"'
);
}


function buildNewCsvRows() {

return results.map(
record =>

COLUMNS
.map(
column =>
escapeCSV(
record[
column
]
)
)
.join(",")
);
}


function downloadCSV() {

if (
!previousCsvText &&
!results.length
) {

alert(
"No detailed post data has been collected or imported."
);


return;
}


const newRows =
buildNewCsvRows();


let parts =
[
"\uFEFF"
];


/*
* Previous CSV already contains
* the header and old rows.
*/

if (
previousCsvText
) {

parts.push(
previousCsvText
);


if (
newRows.length
) {

parts.push(
"\n" +
newRows.join(
"\n"
)
);
}

} else {

/*
* No previous CSV:
* normal fresh export.
*/

parts.push(
COLUMNS.join(
","
)
);


if (
newRows.length
) {

parts.push(
"\n" +
newRows.join(
"\n"
)
);
}
}


const blob =
new Blob(
parts,
{
type:
"text/csv;charset=utf-8;"
}
);


const objectUrl =
URL.createObjectURL(
blob
);


const link =
document.createElement(
"a"
);


link.href =
objectUrl;


link.download =
`${
PROFILE.profile_username ||
"instagram"
}-detailed-post-data-continued.csv`;


document.body.appendChild(
link
);


link.click();


link.remove();


URL.revokeObjectURL(
objectUrl
);
}


/* ============================================================
STOP
============================================================ */

function stop() {

stopRequested =
true;


setStatus(
"Stopping..."
);
}


/* ============================================================
CLEAR
============================================================ */

function clearData() {

if (
running
) {

alert(
"Stop the collector before clearing data."
);


return;
}


const confirmed =
confirm(
"Clear imported CSV data, discovered posts, and new collected records?"
);


if (
!confirmed
) {

return;
}


postUrls.clear();


processedUrls.clear();


results.length =
0;


previousCsvText =
"";


previousCsvFileName =
"";


previousRowCount =
0;


nextRowNumber =
1;


updateCounters();


setStatus(
"All collector data cleared."
);
}


/* ============================================================
START FULL PROCESS
============================================================ */

async function start() {

if (
running
) {

console.log(
"Collector is already running."
);


return;
}


running =
true;


stopRequested =
false;


processingWindow =
window.open(
"about:blank",
"instagramResearchWindow",
"width=1100,height=850"
);


if (
!processingWindow
) {

running =
false;


alert(
"Please allow pop-ups for instagram.com and click Start again."
);


return;
}


try {

/*
* Same previous V3 flow:
*
* scan profile fully
* then process posts
*
* Difference:
* imported URLs are skipped.
*/

await scanProfile();


if (
!stopRequested
) {

await processAllPosts();
}


/*
* Automatic final download.
*/

if (
!stopRequested
) {

setStatus(
`Finished. ${
previousRowCount +
results.length
} total rows. Downloading CSV...`
);


await sleep(
500
);


downloadCSV();


setStatus(
`Finished. ${
previousRowCount +
results.length
} total rows. CSV downloaded.`
);
}


} catch (error) {

setStatus(
`Stopped: ${error.message}`
);


console.error(
error
);


} finally {

running =
false;
}
}


/* ============================================================
FLOATING PANEL
============================================================ */

const panel =
document.createElement(
"div"
);


panel.style.cssText = `

position:fixed;

right:20px;
bottom:20px;

width:305px;

padding:16px;

background:#ffffff;
color:#111;

border:1px solid #ddd;

border-radius:14px;

box-shadow:
0 8px 35px rgba(0,0,0,.24);

font-family:
Arial,sans-serif;

font-size:14px;

z-index:2147483647;

`;


panel.innerHTML = `

<div
style="
font-size:16px;
font-weight:700;
margin-bottom:3px;
"
>
Instagram Post Research
</div>


<div
style="
font-size:12px;
color:#666;
margin-bottom:12px;
"
>
Continue From Previous CSV
</div>


<div
id="ig-v3c-imported"
style="
margin-bottom:4px;
"
>
Previous CSV: not loaded
</div>


<div
id="ig-v3c-found"
style="
margin-bottom:4px;
"
>
Posts found: 0
</div>


<div
id="ig-v3c-processed"
style="
margin-bottom:8px;
"
>
Total records: 0 | New this run: 0
</div>


<div
id="ig-v3c-status"
style="
min-height:42px;

padding:8px;

margin-bottom:10px;

background:#f5f5f5;

border-radius:7px;

color:#555;

font-size:12px;
"
>
Ready
</div>


<button
id="ig-v3c-load"
style="
width:100%;

padding:10px;

margin-bottom:7px;

border:0;

border-radius:7px;

background:#262626;

color:#fff;

font-weight:700;

cursor:pointer;
"
>
Load Previous CSV
</button>


<button
id="ig-v3c-start"
style="
width:100%;

padding:11px;

margin-bottom:7px;

border:0;

border-radius:7px;

background:#0095f6;

color:#fff;

font-weight:700;

cursor:pointer;
"
>
Start / Continue Collection
</button>


<button
id="ig-v3c-stop"
style="
width:100%;

padding:9px;

margin-bottom:7px;

cursor:pointer;
"
>
Stop
</button>


<button
id="ig-v3c-download"
style="
width:100%;

padding:10px;

margin-bottom:7px;

cursor:pointer;
"
>
Download CSV
</button>


<button
id="ig-v3c-clear"
style="
width:100%;

padding:8px;

cursor:pointer;
"
>
Clear Data
</button>

`;


document.body.appendChild(
panel
);


/* ============================================================
BUTTON EVENTS
============================================================ */

document
.getElementById(
"ig-v3c-load"
)
.addEventListener(
"click",
loadPreviousCSV
);


document
.getElementById(
"ig-v3c-start"
)
.addEventListener(
"click",
start
);


document
.getElementById(
"ig-v3c-stop"
)
.addEventListener(
"click",
stop
);


document
.getElementById(
"ig-v3c-download"
)
.addEventListener(
"click",
downloadCSV
);


document
.getElementById(
"ig-v3c-clear"
)
.addEventListener(
"click",
clearData
);


/* ============================================================
CONSOLE API
============================================================ */

window.igResearchCollectorV3Continue = {

start,

stop,

loadPreviousCSV,

download:
downloadCSV,

clear:
clearData,

getNewData:
() => results,

getPostUrls:
() =>
[
...postUrls.keys()
],

getProcessedUrls:
() =>
[
...processedUrls
],

settings:
SETTINGS
};


collectPostUrls();


updateCounters();


console.log(`
Instagram V3 Continue Collector loaded.

IF STARTING FRESH:

1. Click Start / Continue Collection.
2. CSV automatically downloads when finished.

IF CONTINUING FROM YOUR EXISTING FILE:

1. Click Load Previous CSV.
2. Select:
champions_ride-detailed-post-data (1).csv
3. Wait for message showing imported rows.
4. Click Start / Continue Collection.

Example:

Previous CSV ends at row 1327
→ existing post URLs are skipped
→ next new post becomes row 1328
→ row 1329
→ row 1330
→ etc.

FINAL DOWNLOAD:

Old CSV rows
+
new collected rows
=
one combined continued CSV.

Manual options are also available:

Stop
Download CSV
Clear Data
`);

})();

How to fetch instagram posts data?

Fetch Instagram posts data by pasting this code in browser console. (() => { /* ====================================================...