Skip to content

Instantly share code, notes, and snippets.

@thinhbuzz
Last active January 7, 2024 05:15
Show Gist options
  • Save thinhbuzz/5a7df508d7295286fafa7bc109ee2054 to your computer and use it in GitHub Desktop.
Save thinhbuzz/5a7df508d7295286fafa7bc109ee2054 to your computer and use it in GitHub Desktop.
Download all photos from facebook Page
(async () => {
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function getPageId() {
const tags = Array.from(
document.body.querySelectorAll("script:not([src])")
);
for (const tag of tags) {
let matches = tag.textContent.match(/"pageID":"([0-9]+)"/);
if (matches) {
return matches[1];
}
}
return null;
}
function getId() {
try {
const pageId = require('CometRouteStore').getRoute(location.pathname)?.rootView.props.pageID || getPageId();
const result = require('PagesCometPhotosTabMainViewAllPhotosSection_pageConnection.graphql');
if (!pageId || !result) {
throw new Error('Không phải page');
}
return {
pageId,
profileId: null,
collectionId: null,
docId: result.metadata.refetch.operation.params.id,
method: 'PagesCometPhotosTabMainViewAllPhotosSectionPaginationQuery',
};
} catch (e) {
console.error(e);
}
try {
const props = require('CometRouteStore').getRoute(location.pathname)?.rootView.props;
const result = require('ProfileCometAppCollectionPhotosRenderer_collection.graphql');
if (!props || !result) {
throw new Error('Không phải profile');
}
return {
pageId: null,
profileId: props.userID,
collectionId: btoa(`app_collection:${ props.rawSectionToken }:5`),
docId: result.metadata.refetch.operation.params.id,
method: 'ProfileCometAppCollectionPhotosRendererPaginationQuery',
};
} catch (e) {
console.error(e);
}
return { pageId: null, profileId: null, collectionId: null, docId: null, method: null };
}
function prepareData({ dtsg: fb_dtsg, pageId, collectionId, docId: doc_id, method }) {
const variables = pageId
? `{"count":10,"cursor":__CURSOR__,"scale":4,"id":"${ pageId }"}`
: `{"count":8,"cursor":__CURSOR__,"scale":1,"id":"${ collectionId }"}`;
const data = {
doc_id,
fb_dtsg,
variables,
fb_api_caller_class: 'RelayModern',
fb_api_req_friendly_name: method,
};
const formBody = [];
for (const property in data) {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(data[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
return formBody.join('&');
}
async function getLinks({ pageId, method }, formBody) {
return fetch('https://www.facebook.com/api/graphql/', {
headers: {
'content-type': 'application/x-www-form-urlencoded',
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
'x-fb-friendly-name': method,
},
body: formBody,
method: 'POST',
})
.then((response) => response.json())
.then(({ data }) => {
if (pageId) {
return {
images: data.node.allPhotos.edges.map((item) => {
return {
...item.node.image,
...item.node.viewer_image,
};
}),
page: data.node.allPhotos.page_info,
};
}
return {
images: data.node.pageItems.edges.map(
(item) => item.node.node.viewer_image,
),
page: data.node.pageItems.page_info,
};
});
}
window.scrollTo(0, document.body.scrollHeight);
await sleep(1000);
let cursor = null;
const limit = +prompt('Số link tối đa sẽ lấy', '999999') || 999999;
const { pageId, profileId, collectionId, docId, method } = getId();
const dtsg = require('DTSG').getCachedToken ? require('DTSG').getCachedToken() : require('DTSG').getToken();
window.allImages = [];
if ((!pageId && !profileId) || !docId) {
throw new Error('Không tìm thấy token');
}
console.log('%cBắt đầu lấy link', 'color: green;');
const formBody = prepareData({ dtsg, pageId, collectionId, docId, method });
while (true) {
let { images, page } = await getLinks(
{
pageId,
method,
},
formBody.replace('__CURSOR__', cursor ? `"${ cursor }"` : 'null'),
);
window.allImages.push(...images);
console.log('%cĐã lấy được %d link ảnh', 'color: green;', window.allImages.length);
if (!page.has_next_page) {
break;
}
cursor = page.end_cursor;
if (window.allImages.length >= limit) {
break;
}
}
console.log(window.allImages);
const styles = [ 'color: green', 'font-size: 20px', 'padding: 10px' ].join(';');
console.log(
'%cĐã lấy thành công %d link ảnh, gõ copy(window.allImages.map(({ uri }) => uri).join(\'\\n\')) để sao chép links vào clipboard',
styles,
window.allImages.length,
);
})().catch((error) => {
console.log(error);
alert('Vui lòng tải lại trang và thử lại.');
});
@boyboy007000
Copy link

Bác fix giúp mình với. Hết hiệu lực rồi á. Mình nó cứ báo "không phải page" hông à

@thinhbuzz
Copy link
Author

@boyboy007000 chắc là do nó là profile chuyển thành page, mình cũng k nhớ đăng bài này ở đâu nữa

@boyboy007000
Copy link

@boyboy007000 chắc là do nó là profile chuyển thành page, mình cũng k nhớ đăng bài này ở đâu nữa

Em lấy từ bài đăng trên FB đó bác.

Link là này nè : https://www.facebook.com/groups/j2team.community/posts/1617119858620128/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment