Martin McGee's Blog

How to Automate tiktok with Microsoft Playwright

September 18, 2020


Tikok is exploding with popularity, ..why not see if we can automate it? (for education purposes only.. 👀)

The Goal and Challenges

  1. logging into tiktok
  2. upload a video
  3. avoid bot detection and ghosting
  4. ???

1. Setup

Assuming you already have node installed (If you are new to microsoft playwright start here

Create the project, install playwright

mkdir automate-tiktok-tutorial && cd automate-tiktok-tutorial
npm init -y
npm i -D playwright

then create a new file..

mac: touch index.js
windows: echo > index.js

2. Browser Setup & bot detection


Social media sites have advanced bot detection systems to block mass web scrapers and automated tools from using the site.

They will block access from these tools if found.

They have various detection solutions such as:

  • detecting the user agent of the browser using the site (is your automated tool have the user agent of a bot)
  • Ip checking, how may requests coming from your ip, has it been banned before?
  • Real user behavior: is the account logging in at weird times,liking commenting spam or mas uploading posts?
  • Machine learning: Using machine learning to detect fake users (A research paper written here

Tiktok is quite new so hopefully for purposes of this tutorial it isn’t really advanced (yet!)

First let’s see our useragent is leaking any data that we are a bot..:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('');
  await page.screenshot({ path: `example.png` });
  await browser.close();


and run it:

node index.js


Ok so are not being detected as a bot, but we have many different user agent options. we can emulate being on an iphone from the US:

const { webkit, devices } = require('playwright');
const iPhone11 = devices['iPhone 11 Pro'];

(async () => {
  const browser = await webkit.launch();
  const context = await browser.newContext({
    locale: 'en-US',
    geolocation: { longitude: 12.492507, latitude: 41.889938 },
    permissions: ['geolocation']
  const page = await context.newPage();
  await page.goto('');
  await page.screenshot({ path: 'iphone.png' });
  await browser.close();


It is better to do it this way to simulate a real user, but for purposes of this tutorial i’m going with chrome.

3. Logging in

Assuming you already have an tiktok account made (Warning botting could get you banned, try making a practice oen for this)

Now that we have the browser setup, lets login:

  1. navigate to the site
  2. click login
  3. select username/ password
  4. choose email login, and not phone

So lets find the login screen.

clicking the login button brings up an iframe..


Which brings us to the login url without messing around with the iframe stuff and save a few navigation clicks.


OK so lets login..

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({slowMo: 20, headless: false}); //so we can view it
  const page = await browser.newPage();
  await page.goto(''); //login page without the iframe
  await page.fill('[placeholder="Email or Username"','youremail');
  await page.fill('[name=password]','yourpass')
  await browser.close()



3. Operation bypass Captcha

So every login has puzzle captcha..what to do?

We have a few options..

  • Make the bot wait and solve captcha manually (Boring)
  • Machine learning, visual recognition try and solve each symbol? ( don’t want to turn this into a big machine learning tutorial)
  • Change the device location/ emulate different device and see what happens? (tried this didn’t work)
  • use a 3rd party captcha service?
  • Try the SSO options and see if they get captcha?

Let’s try emulating the location/device and see if we still get the same..


Ok so the Captcha is different for mobile, and an easier one to solve too.

But first, lets try logging in with SSO first to see if we get a Captcha..


They don’t check for captcha on Twitter login,

so lets update our script to reflect this.

const { firefox} = require('playwright'); //firefox works better here than chrome

(async () => {
  const browser = await firefox.launch({headless: false}); //lets watch what it's doing
  const context = await browser.newContext();
  const page = await context.newPage();
  //navigate to the iframe where it's hosted avoids messing around with iframe
  await page.goto('');
  //wait for the twitter login screen to popup before continuing
  const newPagePromise = new Promise(x => page.once('popup', x));
  const newPage = await newPagePromise;   // switch to the popup and log into twitter
  await newPage.fill('#username_or_email','your twitter username');
  await newPage.fill('#password','password')
  await newPage.waitForEvent('close')// wait for the twitter popup to confirm before continuing
  await page.goto('');
  await page.screenshot({ path: `ff.png` });
  await browser.close()

The final code is above, we can bypass the tiktok captcha puzzle and then navigate to the upload video page. 👀


In part 2 we will upload a video to tiktok 😁

Feel free to follow me on twitter to wait for part 2!