I am trying to customise a puppeteer script that plays a song on soundcloud and records it. Using a CSS selector I would like to print the song duration as well. I can't seem to get the CSS selector to work. The url I am working with is https://soundcloud.com/octasine/octasine-audio-example-1
I have a working CSS selector now and can grab the minutes and seconds from the page. The challenge I am seeing is that sometimes the page hasn't finished rendering and I get an empty array return using await page.waitForNavigation(); causes the promise to just fail.
What am I missing to get puppeteer to work more reliably?
This is how I am using the CSS selector:
const work = async () => {
const inputsValues = [];
const inputElements = await page.$$('span.sc-visuallyhidden');
for (const element of inputElements) {
let inputValue;
inputValue = await element.getProperty('innerText');
inputValue = await inputValue.jsonValue();
if (inputValue.includes('Duration')){
console.log("DURATION");
mins = inputValue.split(" ")[1];
secs = inputValue.split(" ")[3];
console.log(mins);
console.log(secs);
console.log(inputValue);
}
inputsValues.push(inputValue);
}
console.log(inputsValues)
}
await work();
My complete script example.js:
// example.js -- node version v14.17.2 -- dependency installed with npm i puppeteer-stream
const { launch, getStream } = require("puppeteer-stream");
const fs = require("fs");
const { Console } = require("console");
const file = fs.createWriteStream(__dirname + "/test.webm");
async function test() {
const browser = await launch();
const page = await browser.newPage();
await page.goto("https://soundcloud.com/octasine/octasine-audio-example-1");
// await page.waitForNavigation();
let html_var = await page.content();
// Write the file
fs.writeFile("example.html", html_var, function (err) {
// Checks if there is an error
if (err) return console.log(err);
});
console.log("Wrote html to example.html");
// await page.click("//a[contains(text(), 'Play')]");
await page.evaluate(() => {
let elements = document.getElementsByClassName('snippetUXPlayButton');
for (let element of elements)
element.click();
});
const work = async () => {
const inputsValues = [];
const inputElements = await page.$$('span.sc-visuallyhidden');
for (const element of inputElements) {
let inputValue;
inputValue = await element.getProperty('innerText');
inputValue = await inputValue.jsonValue();
if (inputValue.includes('Duration')){
console.log("DURATION");
mins = inputValue.split(" ")[1];
secs = inputValue.split(" ")[3];
console.log(mins);
console.log(secs);
console.log(inputValue);
}
inputsValues.push(inputValue);
}
console.log(inputsValues)
}
await work();
let page_url = await page.url();
console.log(page_url)
await page.evaluate(() => {
let elements = document.getElementsByClassName('sc-visuallyhidden');
for (let element of elements)
console.log(element.innerHTML);
});
const stream = await getStream(page, { audio: true, video: true });
console.log("recording");
stream.pipe(file);
setTimeout(async () => {
await stream.destroy();
file.close();
console.log("finished");
browser.close();
}, 1000 * 5 + mins * 60000 + secs * 1000);
}
test();
Script based on example script from https://www.npmjs.com/package/puppeteer-stream