Given a TikTok URL that has a video with a transcript I’m trying to write a playwright script that will be able to navigate to grab the transcript. The problem is the hover command doesn’t seem to trigger the menu of video controls that gets injected into the DOM. Even with AI, I still haven’t been able to make this happen so here is the script and let me know if you can see the problem. (Node v20+ with ES6/.mjs)
import { chromium } from "playwright";
import fs from "fs";
import path from "path";
async function scrapeTranscripts(videoIdList) {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
for (const videoId of videoIdList) {
console.log(`Processing video ${videoId}...`);
// Open the video page
const page = await context.newPage();
await page.goto(
`https://www.tiktok.com/@hold_my_hand_wholesale/video/${videoId}`
);
console.log("visit page");
// Delete the #tiktok-verify-ele element
await page.waitForSelector("body > div#tiktok-verify-ele");
await page.$eval("body > div#tiktok-verify-ele", (el) => el.remove());
console.log("remove modal");
// Find controls
const videoControls = await page.waitForSelector(
"div.css-1a3eiq7-DivRightControlsWrapper.e1ya9dnw9"
);
console.log("found dot controls");
// Simulate hovering over the element using Playwright's mouse API
await videoControls.hover();
console.log("mouse hovered");
// Click on the element
const transcriptButton = await page.waitForSelector(
"div.css-1a3eiq7-DivRightControlsWrapper.e1ya9dnw9 > div:nth-child(7) > div > ul > li:nth-child(3)"
);
await transcriptButton.click();
console.log("ts option click");
// Wait for the transcript to load
await page.waitForSelector(
"#main-content-video_detail > div > div > div > div > ul > li > div[class*=DivTranscriptText]"
);
console.log("ts list found");
// Extract the transcript text
const transcriptText = await page.$$eval(
"div[class *= DivTranscriptText]",
(transcripts) =>
transcripts.map((transcript) => transcript.textContent).join("n")
);
console.log("ts compiled");
// Save the transcript to a file in the Download folder
const downloadFolder = "download";
fs.writeFileSync(
`${path.join(downloadFolder, `/video_${videoId}.txt`)}`,
transcriptText
);
console.log("ts saved");
}
await browser.close();
}
const videoIdList = [
"7361535453985787182",
"7349954915441184042",
"7355940770706099498",
"7377122529766427946",
"7377074068723420459",
"7376748158648421678",
];
scrapeTranscripts(videoIdList);
It works if I manually drive to get the transcript.