我有这段代码可以转到关键字的 YouTube 链接,找到不到 5 分钟前上传的视频,并对它们发表评论。
然而,问题是检查选择器 href 的“上传 x mins/secs 前”的循环不起作用,当有那些上传时间的视频时,它只是刷新页面。
我没有尝试任何东西,因为我想不出任何东西。我想要一些帮助,这真的让我很烦。 如果它在没有完整代码的情况下重现问题,我不知道如何在这里制作最少的代码。
这就是问题所在:
// collecting links
let linked = [];
while (linked.length === 0) {
linked = await Promise.all((await page.$$(selector.videoTitleinSearch)).map(async a => {
const uploadedago = await a.$(selector.uploadedago);
if (uploadedago) {
const href = await uploadedago.getProperty('href').jsonValue();
if (href &&
(href.includes("5 minutes ago") ||
href.includes("4 minutes ago") ||
href.includes("3 minutes ago") ||
href.includes("2 minutes ago") ||
href.includes("1 minute ago") ||
href.includes(" seconds ago") ||
href.includes(" second ago"))
) {
return {
url: await a.getProperty('href').jsonValue(),
title: await a.getProperty('title').jsonValue()
};
}
}
return null; // add this line to return null if uploadedago is not found
}));
linked = linked.filter(Boolean); // add this line to remove null values from linked array
if (linked.length === 0) {
console.log("No videos found, refreshing page...");
await page.reload({
waitUntil: "networkidle2"
});
await page.waitForTimeout(5000);
}
下面是所有想要完整代码(main.js)的人的所有代码。
'use strict';
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth')();
const
{
executablePath
} = require('puppeteer');
const cliSpinners = require('cli-spinners');
const Spinners = require('spinnies');
const fs = require('fs');
const config = require("./config")
const cookies = require("./cookies1")
const selector = require("./modules/constant/selector");
const {Config} = require("./modules/constant/BrowserConfig")
const
{
randomUserAgent,
copycommnet,
manualComment,
Logger,
aiCommented,
} = require('./modules');
const { uploadedago } = require('./modules/constant/selector');
const spinners = new Spinners(cliSpinners.star.frames,
{
text: 'Loading',
stream: process.stdout,
onTick(frame, index)
{
process.stdout.write(frame);
},
});
const wait = (seconds) => new Promise((resolve) => setTimeout(() => resolve(true), seconds * 1000));
puppeteer.use(StealthPlugin);
const paths = `${process.cwd()}/ublock`;
StealthPlugin.enabledEvasions.delete('iframe.contentWindow');
['chrome.runtime', 'navigator.languages'].forEach((a) => StealthPlugin.enabledEvasions.delete(a));
async function startApp(config, browserconfig)
{
const keyword = config.keywords;
const browser = await puppeteer.launch({...browserconfig, headless: false});
const page = await browser.newPage();
await page.setViewport(
{
width: 1366,
height: 768
});
await page.evaluateOnNewDocument(() =>
{
delete navigator.__proto__.webdriver;
});
await page.setUserAgent(randomUserAgent.UA());
const loadCookies = async (page, filePath) => {
// Read the cookies from the file
const cookiesString = await fs.promises.readFile(filePath);
const cookies = JSON.parse(cookiesString); // Parse the cookies string into an object
// Set the cookies in the page
await Promise.all(cookies.map((cookie) => {
if (typeof cookie.sameSite !== 'string') {
cookie.sameSite = '';
}
return page.setCookie(cookie);
}));
};
await loadCookies(page, './cookies1.json');
await page.goto('https://www.youtube.com', wait)
console.log('=========== Start Commenting ==============');
spinners.add('first-spinner', {
text: 'Searching for videos..',
color: 'yellow',
});
for (let i = 0; i < keyword.length; i++) {
if (config.usernamec == true) {
await page.goto('https://www.youtube.com/@username');
} else {
await page.goto(`https://www.youtube.com/results?search_query=${keyword[i]}&sp=CAISBAgBEAE%253D&sp=EgIQAQ%253D%253D`);
const element = await page.$(selector.shortvideos);
if (element) {
await page.evaluate(() => {
document.querySelector(selector.shortvideos).remove();
});
}
}
await page.waitForTimeout(3000);
spinners.succeed('first-spinner', {
text: 'done..',
color: 'green'
});
await page.waitForTimeout(7000);
spinners.add('hasil', {
text: 'Collecting videos..',
color: 'yellow'
});
// collecting links
let linked = [];
while (linked.length === 0) {
linked = await Promise.all((await page.$$(selector.videoTitleinSearch)).map(async a => {
const uploadedago = await a.$(selector.uploadedago);
if (uploadedago) {
const href = await uploadedago.getProperty('href').jsonValue();
if (href &&
(href.includes("5 minutes ago") ||
href.includes("4 minutes ago") ||
href.includes("3 minutes ago") ||
href.includes("2 minutes ago") ||
href.includes("1 minute ago") ||
href.includes(" seconds ago") ||
href.includes(" second ago"))
) {
return {
url: await a.getProperty('href').jsonValue(),
title: await a.getProperty('title').jsonValue()
};
}
}
return null; // add this line to return null if uploadedago is not found
}));
linked = linked.filter(Boolean); // add this line to remove null values from linked array
if (linked.length === 0) {
console.log("No videos found, refreshing page...");
await page.reload({
waitUntil: "networkidle2"
});
await page.waitForTimeout(5000);
}
// check if any links were found before refreshing the page
if (linked.length > 0) {
console.log(`Found ${linked.length} links`);
} else {
console.log("No videos found");
}
const link = linked.filter(el => el.url != null);
spinners.succeed('hasil', {
text: `FOUND ${link.length} LINKS`,
color: 'green',
});
for (i in link) {
if (readLog().includes(link[i].url)) {
spinners.add('already', {
text: 'already commented on video..',
color: 'red',
});
continue;
}
spinners.add('comment', {
text: 'commenting on video..',
color: 'yellow',
});
const tweet = link[i].url;
const title = link[i].title;
const pages = await browser.newPage();
await pages.setViewport({
width: 1366,
height: 768
});
await pages.setUserAgent(randomUserAgent.UA());
if (tweet.includes("shorts")) {
await pages.goto(tweet.replace(/shorts/, "watch"));
} else {
await pages.goto(tweet);
}
try {
await likeVideos.likeVideos(pages);
await commentVideos.commentVideos(pages, config.message);
addToLog(link[i].url);
spinners.succeed('comment', {
text: 'commented on video..',
color: 'green',
});
console.log(`Commented on video "${title}"`);
} catch (error) {
console.log(`Error while commenting on video "${title}": ${error}`);
spinners.fail('comment', {
text: 'commenting failed',
color: 'red',
});
}
await pages.close();
await page.waitForTimeout(15000);
}}}
console.log('COMMENTED ..');
startApp(config, Config(paths,config,executablePath("chrome")));
function readLog()
{
const data = fs.readFileSync('./logs/succesCommenting.log', 'utf8');
return data;
}
这里是选择器列表(./constants/selectors/):
module.exports = {
checkLogin : "#yDmH0d > c-wiz > div > div:nth-child(2) > div > c-wiz > c-wiz > div > div.s7iwrf.gMPiLc.Kdcijb > div > div > header > h1",
username : "#identifierId",
password: "input",
showpass : "#selectionc1",
shortvideos : ".ytd-section-list-renderer > #contents > .style-scope:nth-child(1)",
videoTitleinSearch : "#video-title",
shortsTitleinSearch : "#details > a",
catchErrorInComment : "#message > span",
inputComment : "#simplebox-placeholder",
uploadedago : "#metadata-line > span:nth-child(4)",
}
这里是评论的配置文件:
module.exports = {
keywords: ["cats"],
comments: ["hi", "hello", "nice"],
delaycomment: 60, // delay ( per second )
trending: false,
copycomment:false, // false if you want use comment above , i mean from array
userdatadir : "fdciabdul",
ai : false, // true if you want to use OPEN AI (CHAT-GPT) auto comment
apiKey : "",
};
对于cookie,您需要从浏览器的扩展中导出它们。
免责声明:我仅将此用于我自己的频道,我只是在努力上传视频之前使用其他视频来验证一切是否正常,只是为了找出不正常的地方;所以这更容易测试。