We've got an incredible 90% Off Subscription Deal just for you! Now, you can enjoy the following unbeatable prices:
- Professional Plan: Only $29.9/month (original price $299)
- Enterprise Plan: Only $59.9/month (original price $599)
What’s more, you’ll keep enjoying these discounts with auto-renewal! No extra steps needed—your discount will be automatically applied at renewal.
Before we start the tutorial, let's first understand what Nstbrowser and Nstbrowser docker are.
Nstbrowser is a powerful fingerprint browser that provides a real browser environment for each user's account. Each browser is isolated from each other, and can achieve cross-platform environment simulation. Based on fingerprint browser technology, it can easily bypass account tracking and detection of various sites.
Nstbrowser docker is a docker image built based on Nstbrowser. Due to limited local resources, we can easily deploy Nstbrowser to cloud services through docker. Based on the cloud synchronization function, we can directly use Nstbrowser in Nstbrowser docker to create a cultivated browser environment.
Next, we will demonstrate how to use Nstbrowser docker to automatically click like TikTok (Note: TikTok has strict account risk control prevention, please try not to use newly created accounts)
docker pull docker.io/nstbrowser/browserless:latest
docker run -d -it \
-e TOKEN="YOU API KEY" \
-p 8848:8848 \
--name nstbrowserless \
nstbrowser/browserless:latest
Here we use puppeteer-core
+ axios
to demonstrate
# pnpm
pnpm i puppeteer-core axios
# yarn
yarn add puppeteer-core axios
# npm
npm i --save puppeteer-core axios
Before using puppeteer to connect to Nstbrowser, we need to start Nstbrowser first, start the interface: http://localhost:8848/start/{profileId}. You can check the specific interface details and parameters on the official website:
const baseUrl = 'localhost:8848'
const profileId = 'YOU_PROFILEID'
async function startBrowser() {
const config = {
"name": "tiktok_star",
"platform": "windows",
"kernel": "chrome",
"kernelMilestone": "130",
// "proxy": "http://127.0.0.1:8000", // You can use custom proxy
// "fingerprint": { // configure custom fingerprint parameters
// "flags": {
// "timezone": "BasedOnIp",
// "screen": "Custom"
// },
// },
// "args": {
// "--proxy-bypass-list": "*.nstbrowser.io" // configure custom start parameters
// }
};
return axios.post(`http://${baseUrl}/start/${profileId}`, JSON.stringify((config)), { headers: { 'Content-Type': 'application/json' } })
.then((response) => {
if (response.data.code === 200) {
return true
}
})
.catch((error) => {
console.error(error);
});
}
We navigate to the TikTok website. And get the input box element and the OK button in the web page through the developer tool (F12):
Enter the user content you want to view:
const page = await browser.newPage();
await page.goto('https://www.tiktok.com/');
await page.waitForSelector('input[type=search]')
await page.type('input[type=search]', 'WillSmith', { delay: '100' })
await page.waitForSelector('div.css-1fxbsrz-DivVideoListScrollBar.e10wilco12 > div > div:nth-child(1) a')
await page.click('div.css-1fxbsrz-DivVideoListScrollBar.e10wilco12 > div > div:nth-child(1) a')
Sometimes, when entering the playback page, the small window mode will be used by default. We need to restore the window:
try {
await page.waitForSelector('button.e12q9uh55.css-1xiq6b1-Button-ButtonReturn.e1v8cfre0', { timeout: 3000 });
// close PictureInPicture
await page.click('button.e12q9uh55.css-1xiq6b1-Button-ButtonReturn.e1v8cfre0')
} catch (e) {
console.log("cant find close button")
}
Wait for the video to play for a while before liking it
// wait for the video to play for a while
await new Promise(resolve => setTimeout(resolve, 10000));
// give a like
await page.click('button.css-1mizk9b-ButtonActionItem.e1hk3hf90')
Then slide the video to the next one and repeat this operation:
const boundingBox = await page.$('body video').then(el => el.boundingBox());
for (let i = 0; i < 3; i++) {
// wait for the video to play for a while
await new Promise(resolve => setTimeout(resolve, 10000));
// give a like
await page.click('button.css-1mizk9b-ButtonActionItem.e1hk3hf90')
// move the mouse to the center of the video
await page.mouse.move(
boundingBox.x + boundingBox.width / 2,
boundingBox.y + boundingBox.height / 2
);
// scroll the video down
await page.mouse.wheel({ deltaY: 100 });
}
import puppeteer from 'puppeteer-core';
import axios from 'axios';
const baseUrl = 'localhost:8848'
const profileId = 'YOU_PROFILEID'
async function startBrowser() {
const config = {
"name": "tiktok_star",
"platform": "windows",
"kernel": "chrome",
"kernelMilestone": "130",
// "proxy": "http://127.0.0.1:8000",
// "doProxyChecking": false,
// "fingerprint": {
// "flags": {
// "timezone": "BasedOnIp",
// "screen": "Custom"
// },
// },
// "args": {
// "--proxy-bypass-list": "*.nstbrowser.io"
// }
};
return axios.post(`http://${baseUrl}/start/${profileId}`, JSON.stringify((config)), { headers: { 'Content-Type': 'application/json' } })
.then((response) => {
if (response.data.code === 200) {
return true
}
})
.catch((error) => {
console.error(error);
});
}
async function execPuppeteer() {
try {
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://${baseUrl}/connect/${profileId}`
});
const page = await browser.newPage();
await page.goto('https://www.tiktok.com/');
await page.waitForSelector('input[type=search]')
await page.type('input[type=search]', 'WillSmith', { delay: '100' })
await page.click('button[data-e2e=search-box-button]')
await page.waitForSelector('div.css-1fxbsrz-DivVideoListScrollBar.e10wilco12 > div > div:nth-child(1) a')
// div.css-1fxbsrz-DivVideoListScrollBar.e10wilco12
await page.click('div.css-1fxbsrz-DivVideoListScrollBar.e10wilco12 > div > div:nth-child(1) a')
try {
await page.waitForSelector('button.e12q9uh55.css-1xiq6b1-Button-ButtonReturn.e1v8cfre0', { timeout: 3000 });
// close PictureInPicture
await page.click('button.e12q9uh55.css-1xiq6b1-Button-ButtonReturn.e1v8cfre0')
} catch (e) {
console.log("cant find close button")
}
await page.waitForSelector('button[data-e2e=arrow-right]')
await page.click('button[data-e2e=arrow-right]')
// get the video bounding box
const boundingBox = await page.$('body video').then(el => el.boundingBox());
for (let i = 0; i < 3; i++) {
// wait for the video to play for a while
await new Promise(resolve => setTimeout(resolve, 10000));
// give a like
await page.click('button.css-1mizk9b-ButtonActionItem.e1hk3hf90')
// move the mouse to the center of the video
await page.mouse.move(
boundingBox.x + boundingBox.width / 2,
boundingBox.y + boundingBox.height / 2
);
// scroll the video down
await page.mouse.wheel({ deltaY: 100 });
}
await browser.close()
} catch (e) {
console.error(e)
}
}
(async () => {
const ok = await startBrowser()
if (ok) {
await execPuppeteer()
}
})();
Nstbrowser's cloud synchronization function can create a profile on any device and synchronize the profile to other devices and docker environments.
Cloud synchronization can retain the content and history of the page you last visited, greatly simplifying the operation cost. And the same profile environment is the same on any device, which can prevent device detection in the site. Cloud synchronization cookies can synchronize user cookie data together, and the login status based on cookies can also be synchronized to the same profile environment.