FREE way to scrape Tiktok videos!

I wrote a script that will scrape Tiktok videos for you.

You need to be logged in.

Here's a video on how to use the script:

https://www.youtube.com/watch?v=wyXqFDXp27c

Tiktok caps the number of search results at about 400, so this will return a max of 400 on each run.

If you want to scrape other sites, check out my brand new AI scraper: ScrapeThat.ai

Here's a video on how to use the script:

Written instructions:

  1. Go to Tiktok (must be logged in)
  2. Search for something
  3. Go to the "Videos" tab
  4. Open the browser console (right-click -> inspect -> console)
  5. Paste the script below and hit enter
  6. Wait for the magic 🧙‍♂️
function createCSV(data, fileName) {
  const headers = Object.keys(data[0])

  const csvContent = [
    headers.join(','),
    ...data.map((row) =>
      headers
        .map((header) => {
          const value = row[header]
          if (value === null) return 'null'
          if (typeof value === 'string') {
            // Wrap all fields, including those without commas, in double quotes
            return `"${value.replace(/"/g, '""')}"`
          }
          return value
        })
        .join(','),
    ),
  ].join('\n')

  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
  const link = document.createElement('a')

  if (navigator.msSaveBlob) {
    // IE 10+
    navigator.msSaveBlob(blob, fileName)
  } else {
    const url = URL.createObjectURL(blob)

    link.setAttribute('href', url)
    link.setAttribute('download', fileName || 'data.csv')
    document.body.appendChild(link)

    link.click()

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

function autoScroll() {
  return new Promise((resolve, reject) => {
    let lastHeight = document.body.scrollHeight,
      newHeight
    const interval = setInterval(async () => {
      window.scrollTo(0, document.body.scrollHeight)
      console.log(
        `Don't worry if you see errors. Give it a few minutes to run.`,
      )
      console.log(`Check out my site: https://thewebscrapingguy.com`)
      console.log(
        'If you need Tiktok leads, check out my product: https://tokfinder.co/',
      )
      console.log(
        '100k+ TikTok accounts (with emails) for just $97: https://tokfinder.co/',
      )
      console.log(
        'Or if you want to scrape many sites, check out my AI scraper: https://scrapethat.ai/',
      )
      await new Promise((r) => setTimeout(r, 3000))

      newHeight = document.body.scrollHeight
      if (lastHeight === newHeight) {
        clearInterval(interval)
        console.log(
          'Reached the bottom: No more content to load or infinite scroll limit reached.',
        )
        resolve('Done Scrolling') // Resolve the promise
      } else {
        lastHeight = newHeight
      }
    }, 3000) // You might need to adjust this interval
  })
}

function getDeepestLastChild(element) {
  if (element.lastElementChild) {
    // If there's a last child, go deeper
    return getDeepestLastChild(element.lastElementChild)
  } else {
    // If there are no more child elements, return the current element
    return element
  }
}

function getVideosFromHtml() {
  const all = []
  const els = document.querySelectorAll(
    '[data-e2e="search_video-item-list"] > div',
  )
  // find the first a tag and get the href
  els.forEach((el) => {
    const videoItem = el.querySelector('[data-e2e="search_video-item"]')
    const postUrl = videoItem.querySelector('a').getAttribute('href')
    // const videoSrc = videoItem.querySelector("video").getAttribute("src");
    const coverSrc = videoItem.querySelector('img').getAttribute('src')
    const videoDescription = el.querySelector('[data-e2e="search-card-desc"]')
    const date = el.querySelector(
      'div > div > a > div > div:last-child > div',
    )?.textContent
    const caption = videoDescription.querySelector(
      '[data-e2e="search-card-video-caption"]',
    )?.textContent

    const uniqueId = el.querySelector(
      '[data-e2e="search-card-user-unique-id"]',
    )?.textContent

    const likes = el.querySelector(
      '[data-e2e="search-card-like-container"]',
    )?.textContent

    all.push({
      postUrl,
      caption,
      profileUrl: `https://www.tiktok.com/@${uniqueId}`,
      handle: uniqueId,
      likes: parseLikeCount(likes),
      date,
      coverSrc,
    })
  })
  return all
}

function parseLikeCount(likes) {
  // likes is a string like "1.2M" or "1345" or "10.5K" anything more thank 1k is shortened
  const num = parseFloat(likes)
  if (likes.includes('M')) {
    return num * 1000000
  } else if (likes.includes('K')) {
    return num * 1000
  } else {
    return num
  }
}

;(async function () {
  await autoScroll()
  const videos = getVideosFromHtml()
  console.log('videos', videos)
  console.log(`🥳 Woohoo! You just scraped ${videos.length} tiktok videos!`)
  console.log('If you need Tiktok leads, check out https://tokfinder.co/')
  console.log(
    '100k+ TikTok accounts (with emails) for just $97: https://tokfinder.co/',
  )
  const urlObj = new URL(window.location.href)
  const searchQuery = urlObj.searchParams.get('q')
  createCSV(videos, `${searchQuery}-tiktok-videos.csv`)
})()

Sign up for my email list

Sign Up