instagram: yet another fix for post downloading (#441)
This commit is contained in:
commit
ea9d83c79c
1 changed files with 112 additions and 28 deletions
|
@ -60,16 +60,41 @@ async function request(url, cookie, method = 'GET', requestData) {
|
||||||
return data.json();
|
return data.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPost(id) {
|
async function requestHTML(id, cookie) {
|
||||||
let data;
|
const data = await fetch(`https://www.instagram.com/p/${id}/embed/captioned/`, {
|
||||||
try {
|
headers: {
|
||||||
const cookie = getCookie('instagram');
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||||
|
"Accept-Language": "en-GB,en;q=0.9",
|
||||||
|
"Cache-Control": "max-age=0",
|
||||||
|
"Dnt": "1",
|
||||||
|
"Priority": "u=0, i",
|
||||||
|
"Sec-Ch-Ua": 'Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99',
|
||||||
|
"Sec-Ch-Ua-Mobile": "?0",
|
||||||
|
"Sec-Ch-Ua-Platform": "macOS",
|
||||||
|
"Sec-Fetch-Dest": "document",
|
||||||
|
"Sec-Fetch-Mode": "navigate",
|
||||||
|
"Sec-Fetch-Site": "none",
|
||||||
|
"Sec-Fetch-User": "?1",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
|
||||||
|
...cookie
|
||||||
|
}
|
||||||
|
}).then(r => r.text());
|
||||||
|
|
||||||
|
let embedData = JSON.parse(data?.match(/"init",\[\],\[(.*?)\]\],/)[1]);
|
||||||
|
|
||||||
|
if (!embedData || !embedData?.contextJSON) return false;
|
||||||
|
|
||||||
|
embedData = JSON.parse(embedData.contextJSON);
|
||||||
|
|
||||||
|
return embedData;
|
||||||
|
}
|
||||||
|
async function requestGQL(id, cookie) {
|
||||||
let dtsgId;
|
let dtsgId;
|
||||||
|
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
dtsgId = await findDtsgId(cookie);
|
dtsgId = await findDtsgId(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = new URL('https://www.instagram.com/api/graphql/');
|
const url = new URL('https://www.instagram.com/api/graphql/');
|
||||||
|
|
||||||
const requestData = {
|
const requestData = {
|
||||||
|
@ -84,15 +109,50 @@ async function getPost(id) {
|
||||||
requestData.fb_dtsg = dtsgId;
|
requestData.fb_dtsg = dtsgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (await request(url, cookie, 'POST', requestData))
|
return (await request(url, cookie, 'POST', requestData))
|
||||||
.data
|
.data
|
||||||
?.xdt_api__v1__media__shortcode__web_info
|
?.xdt_api__v1__media__shortcode__web_info
|
||||||
?.items
|
?.items
|
||||||
?.[0];
|
?.[0];
|
||||||
} catch {}
|
}
|
||||||
|
|
||||||
if (!data) return { error: 'ErrorCouldntFetch' };
|
function extractOldPost(data, id) {
|
||||||
|
const sidecar = data?.gql_data?.shortcode_media?.edge_sidecar_to_children;
|
||||||
|
if (sidecar) {
|
||||||
|
const picker = sidecar.edges.filter(e => e.node?.display_url)
|
||||||
|
.map(e => {
|
||||||
|
const type = e.node?.is_video ? "video" : "photo";
|
||||||
|
const url = type === "video" ? e.node?.video_url : e.node?.display_url;
|
||||||
|
|
||||||
|
return {
|
||||||
|
type, url,
|
||||||
|
/* thumbnails have `Cross-Origin-Resource-Policy`
|
||||||
|
** set to `same-origin`, so we need to proxy them */
|
||||||
|
thumb: createStream({
|
||||||
|
service: "instagram",
|
||||||
|
type: "default",
|
||||||
|
u: e.node?.display_url,
|
||||||
|
filename: "image.jpg"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (picker.length) return { picker }
|
||||||
|
} else if (data?.gql_data?.shortcode_media?.video_url) {
|
||||||
|
return {
|
||||||
|
urls: data.shortcode_media.video_url,
|
||||||
|
filename: `instagram_${id}.mp4`,
|
||||||
|
audioFilename: `instagram_${id}_audio`
|
||||||
|
}
|
||||||
|
} else if (data?.gql_data?.shortcode_media?.display_url) {
|
||||||
|
return {
|
||||||
|
urls: data.gql_data?.shortcode_media.display_url,
|
||||||
|
isPhoto: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractNewPost(data, id) {
|
||||||
const carousel = data.carousel_media;
|
const carousel = data.carousel_media;
|
||||||
if (carousel) {
|
if (carousel) {
|
||||||
const picker = carousel.filter(e => e?.image_versions2)
|
const picker = carousel.filter(e => e?.image_versions2)
|
||||||
|
@ -133,7 +193,31 @@ async function getPost(id) {
|
||||||
isPhoto: true
|
isPhoto: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPost(id) {
|
||||||
|
let data, result, dataType = 'old';
|
||||||
|
try {
|
||||||
|
const cookie = getCookie('instagram');
|
||||||
|
|
||||||
|
data = await requestHTML(id);
|
||||||
|
if (!data && cookie) data = await requestHTML(id, cookie);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
dataType = 'new';
|
||||||
|
data = await requestGQL(id, cookie);
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
if (!data) return { error: 'ErrorCouldntFetch' };
|
||||||
|
|
||||||
|
if (dataType === 'new') {
|
||||||
|
result = extractNewPost(data, id)
|
||||||
|
} else {
|
||||||
|
result = extractOldPost(data, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) return result;
|
||||||
return { error: 'ErrorEmptyDownload' }
|
return { error: 'ErrorEmptyDownload' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue