puppeteer-extra
puppeteer-extra copied to clipboard
Tiktok detecting puppeteer-extra-stealth-plugin in headful
Hey there,
I'm exploring the possibility of automating video posting on TikTok by using the web version. I've created a puppeteer script that logs in, goes to the upload page, upload a video and then attempts to post it.
Everything works fine until I try to click the final "post" button. In a real browser environment, when I click this button, the post is sent successfully. However, when running in a browser controlled via Puppeteer, clicking this button doesn't do anything. This leads me to think that tiktok is detecting this as a bot and blocking the posting action.
Things to note, the upload form is embedded inside an iframe in the page.
Has anyone managed to trigger a post action on titkok using puppeteer? And if not, what could I do to further investigate the problem?
Here's my script:
import puppeteer from "puppeteer-extra";
// add stealth plugin and use defaults (all evasion techniques)
import stealthPlugin from "puppeteer-extra-plugin-stealth";
puppeteer.use(stealthPlugin());
const email = "a_username";
const password = "a_password";
const videoPath = "in.mp4";
// wait for post button to be clickable, then click it to post video
const sendPost = async (page, tryCount = 1) => {
try {
const sendPostSelector = ".btn-post:not(.disabled)";
await page.waitForSelector(sendPostSelector);
console.log(">>> load video success");
console.log(">>> try send post: ", tryCount);
// await page.click(sendPostSelector);
await page.hover(sendPostSelector);
console.log(">>> hover success");
await page.evaluate(() => {
function emulateButtonClick(selector) {
// Get the button element by its ID
var button = document.querySelector(selector);
// Check if the button exists
if (!button) {
console.log(`No element with id ${selector} found.`);
return;
}
// Create a new 'click' event
var mouseEnterEvent = new MouseEvent("mouseover", {
view: window,
bubbles: true,
cancelable: true,
});
var clickEvent = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
});
// Dispatch the event on the button
button.dispatchEvent(mouseEnterEvent);
button.dispatchEvent(clickEvent);
}
emulateButtonClick(".btn-post");
});
console.log(">>> click success");
} catch (error) {
console.log("error: ", error);
if (tryCount === 4) {
console.log(">>> skip profile");
return;
}
await new Promise((resolve) => setTimeout(resolve, 1000));
tryCount += 1;
await sendPost(page, tryCount);
}
};
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
const timeout = 15000;
page.setDefaultTimeout(timeout);
await page.goto("https://www.tiktok.com/login/phone-or-email/email");
await page.type("input[name=username]", email, { delay: 100 });
await page.type("input[placeholder=Password]", password, { delay: 100 }); // log in w email and password
await page.evaluate(() => {
// @ts-ignore
document.querySelector("button[type=submit]").click();
}); // press login button
await page.waitForNavigation(); // wait for page to load
await page.goto("https://www.tiktok.com/upload?lang=en"); // go to upload page
// Upload form is embedded in an iframe
console.log("waiting for iframe with form to be ready.");
const iframe = await page.waitForSelector("iframe");
const formFrame = await iframe.contentFrame();
console.log(formFrame);
await new Promise((resolve) => setTimeout(resolve, 5000)); // wait for page to load
await formFrame.click(".upload-card");
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
formFrame.click(".upload-card"),
]);
await fileChooser.accept([videoPath]);
// send post
await new Promise((resolve) => setTimeout(resolve, 10000)); // wait for page to load
await sendPost(formFrame);
await browser.close();
})().catch((err) => {
console.error(err);
process.exit(1);
});
Versions
System: OS: macOS 13.3 CPU: (8) arm64 Apple M2 Memory: 106.81 MB / 8.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.20.0 - /usr/local/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 9.6.6 - /usr/local/bin/npm npmPackages: puppeteer: ^20.3.0 => 20.3.0 puppeteer-extra: ^3.3.6 => 3.3.6 puppeteer-extra-plugin-stealth: ^2.11.2 => 2.11.2
possible is chrome upgrade to 114
@ganguoyin what to you mean?
@ganguoyin what to you mean?
The user above meant that you should update your chromium to the latest version which is now 116 i believe
Solution: Use latest Chrome version and avoid using Chrome Test build which Puppeteer installs/uses by default.
I'm having the exact same problem... Login and upload works fine until I try to click the "Post" button. Have you found a fix? Puppeteer is on version 117.0.5938.92, so that is not the issue...