top of page
  • Writer's pictureJack Chen

population infinite: puppeteer

For this week’s class we are assigned to write a script using puppeteer to automate one of our online activities.

Without prior knowledge in coding with vs code, PowerShell, or terminal, I had to first familiarize the basic workflow before coding the puppeteer. I did this by following the class recording and watching videos about the basic layout of vs code and js as I went. At first I ran the code using PowerShell but later on I discovered that opening a terminal on vs code is a more convenient way to write and run code together in one window.

For my puppeteer I decided to make a bot which searches up vaporwave music and clicks on the first result along with the recommendation videos after the first video. In this case, instead of constructing a misleading identity, the purpose of my puppeteer would be to further emphasize my interest in vaporwave music to the algorithm in the hopes of receiving more vaporwave music recommendations from YouTube.

At first I wrote and pasted the code for clicking on a related video multiple times in order to get the puppeteer to click on new videos, but later I noticed that there was an example code doing the same thing I was trying to do but using a loop code instead of pasting the same code multiple times. I copied the loop from the example into my sketch but I am not fully sure how it works yet. specifically, I can see the comments explaining the function of each element which was easy to follow, but I am not sure which part of the code made the functions into a repeating loop rather than something which only performs once.

const watchDuration = 5; while(true) { await page.waitFor('h1 yt-formatted-string'); const videoTitle = await page.evaluate(function() { return document.querySelector('h1 yt-formatted-string').innerText; }); console.log('watching video ' + videoTitle); // watch the video for the watchDuration seconds await page.waitFor(watchDuration * 1000); await page.waitForSelector('#related #items #contents a'); await page.click('#related #items #contents a'); }

The while(true) seems to be the conditional statement which loops the functions, but I am not sure how that statement works and which is the Boolean variable it checks to loop the statement.

After finishing the first part of my puppeteer, I decided to make the bot “like” every video it watches. While I was able to make the bot perform the action of clicking the “like” button, the likes are not performed in the actual video as you could need to login in order to like videos on YouTube. I know the puppeteer is clicking the like button because I wrote a console log report for when the bot clicked like, and when running with the browser open I can see the YouTube reminder to register in order to like videos popping up.


registration reminder notification for when liking a video without logging in

I tried making the video likes go through by letting the puppeteer wait for me to manually log in before performing the rest of its actions. I tried a few different selectors for the puppeteer to wait for to appear before running the rest of the lines but many elements are not unique to a logged in webpage. In the end I found out that the profile avatar button is unique to a logged in YouTube page so I made the puppeteer wait for that element to appear as a way to wait for me to manually login.

Unfortunately it turns out that google accounts cannot be logged in on the Chromium browser which the puppeteer runs on, so as of now I am not able to login to my account in order for the puppeteer to successfully “like” videos. However, since I was able to get the puppeteer to perform the action of clicking the “like” button, my code should be able to perform the full routine of looking up vaporwave music, clicking through the result and the recommendations, and liking each video it comes across if I can find a way to bypass the incompatibility of logging in on chromium.

Below is the current version of my puppeteer code, I commented out the section for waiting for a manual login.

“`


//a puppeteer that goes on my youtube account and looks up vaporwave playlists…

//so youtube can recommend me more of that a e s t h e t i c music 😀

//can’t login to youtube on chromium, if able to login one day, uncomment lines 25-37 to manually login

//can’t “like” video on youtube without logging in, but the like command works because the “login to make your opinion count” window pops ups on each video page

//paste below line into powershell to run

//node –harmony-top-level-await Jackspuppeteer.js

import puppeteer from ‘puppeteer’;

const browser = await puppeteer.launch({headless: false});

// create a page

const context = await browser.createIncognitoBrowserContext();

const page = await context.newPage();

//go to youtube

await page.goto(‘https://www.youtube.com/’)

await page.setViewport({ width: 1536, height: 722 })

// console.log(‘open the browser window, and login to youtube:’);

// // wait for profilePic to appear.

// const profilePic = await page.waitForSelector(‘#avatar-btn’);

// // let the page load

// await page.waitForTimeout(3000);

// await page.waitForSelector(‘#avatar-btn’);

// // let the page load

// await page.waitForTimeout(3000);

//click search

await page.waitForSelector(‘#search > #search-form > #container #search’)

await page.click(‘#search > #search-form > #container #search’)

slowMo: 250

console.log(‘searching up vaporwave’)

//search “vaporwave mix”

await page.type(‘#search > #search-form > #container #search’, ‘vaporwave mix’, {delay: 60})

await page.keyboard.press(‘Enter’);

console.log(‘selecting first video’)

slowMo: 250

//select first video

await page.waitForSelector(‘.ytd-item-section-renderer:nth-child(2) > #dismissable > .text-wrapper > #meta > #title-wrapper > .title-and-badge > #video-title > .style-scope’)

await page.click(‘.ytd-item-section-renderer:nth-child(2) > #dismissable > .text-wrapper > #meta > #title-wrapper > .title-and-badge > #video-title > .style-scope’)

console.log(‘click like button’)

const likeButton = await page.waitForSelector(‘#top-level-buttons > ytd-toggle-button-renderer:nth-child(1) > a’);

await page.waitForSelector(‘#top-level-buttons > ytd-toggle-button-renderer:nth-child(1) > a’)

await likeButton.click();

console.log(‘clicking on related video’)

slowMo:250

await page.waitForSelector(‘#related #items #contents a’);

await page.click(‘#related #items #contents a’);

//click on more related video

const watchDuration = 5;

while(true) {

await page.waitFor(‘h1 yt-formatted-string’);

const videoTitle = await page.evaluate(function() {

return document.querySelector(‘h1 yt-formatted-string’).innerText;

});

console.log(‘watching video ‘ + videoTitle);

// watch the video for the watchDuration seconds

await page.waitFor(watchDuration * 1000);

//click like button

console.log(‘click like button’)

const likeButton = await page.waitForSelector(‘#top-level-buttons > ytd-toggle-button-renderer:nth-child(1) > a’);

await page.waitForSelector(‘#top-level-buttons > ytd-toggle-button-renderer:nth-child(1) > a’)

await likeButton.click();

//click next related video

await page.waitForSelector(‘#related #items #contents a’);

await page.click(‘#related #items #contents a’);

}

“`

4 views0 comments

Recent Posts

See All
bottom of page