SA
Skip to main content

카카오스토리 완전백업

역사의 집대성

우선 설정에 들어가서 아카이브를 다운로드해둔다. 그렇게 해야지만 사진이 백업된다.

그 다음 다음 코드를 콘솔에서 구동한다. 자동으로 맨 아래까지 스크롤해준다.

function scrollToBottomOfInfiniteScroll() {
let lastHeight = 0
let timer = setInterval(() => {
window.scrollTo(0, document.documentElement.scrollHeight)

let currentHeight = document.documentElement.scrollHeight
if (currentHeight === lastHeight) {
clearInterval(timer)
console.log('Reached the bottom or new content is not loading.')
} else {
lastHeight = currentHeight
}
}, 2000) // 2000 milliseconds (or 2 seconds) between each scroll attempt
}

scrollToBottomOfInfiniteScroll()

그 다음 이를 실행한다.

async function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}

async function clickAndWaitForFeed(elementToClick) {
return new Promise((resolve) => {
const feedObserver = new MutationObserver((mutations, observer) => {
for (let mutation of mutations) {
if (mutation.type === 'childList' && document.querySelector('.feed')) {
observer.disconnect()
resolve()
}
}
})

feedObserver.observe(document.body, { childList: true, subtree: true })

elementToClick.click()
})
}

async function downloadTextContent(filename, content) {
const blob = new Blob([content], { type: 'text/plain' })
const url = URL.createObjectURL(blob)

const a = document.createElement('a')
a.href = url
a.download = filename
a.style.display = 'none'
document.body.appendChild(a)

a.click()

URL.revokeObjectURL(url)
document.body.removeChild(a)
}

async function waitForElement(selector) {
return new Promise((resolve) => {
const element = document.querySelector(selector)
if (element) {
resolve(element)
return
}

const observer = new MutationObserver((mutations, observerInstance) => {
const foundElement = document.querySelector(selector)
if (foundElement) {
observerInstance.disconnect()
resolve(foundElement)
}
})

observer.observe(document.body, { childList: true, subtree: true })
})
}

async function processActivity(activity) {
const linkPost = activity.querySelector('._linkPost')
if (!linkPost) return

await clickAndWaitForFeed(linkPost)
await delay(5000) // Adjusted delay to 5 seconds

const cover = await waitForElement('#cover')

const btnShowFirstComment = cover.querySelector('._btnShowFirstComment')
btnShowFirstComment?.click()

await delay(5000) // Adjusted delay to 5 seconds

const timeValue = cover.querySelector('.time').innerText
downloadTextContent(`${timeValue}.txt`, cover.innerText)
}

async function main() {
const activities = document.querySelectorAll('._activity')
for (let activity of activities) {
await processActivity(activity)
}
}

main()