Puppeteer can't click on li element - javascript

I'm trying to access a telegram conversation at https://web.telegram.org/k/. I can't click on the li element, I've tried several ways like page.click() and document.querySelector("xxxxxx").click() but nothing works.
Here's my code:
const pup = require('puppeteer')
const url = 'https://web.telegram.org/k/'
async function inicializar() {
const browser = await pup.launch({
headless: false
})
const page = await browser.newPage()
await page.goto(url)
await page.waitForTimeout(15000)
await page.evaluate(() => {
document.querySelector("#auth-pages > div > div.tabs-container.auth-pages__container > div.tabs-tab.page-signQR.active > div > div.input-wrapper > button > div").click()
})
await page.waitForTimeout(5000)
try {
await page.evaluate(() => {
document.querySelector("#auth-pages > div > div.tabs-container.auth-pages__container > div.tabs-tab.page-signQR.active > div > div.input-wrapper > button:nth-child(2) > div").click()
})
} catch {
await page.evaluate(() => {
document.querySelector("#auth-pages > div > div.tabs-container.auth-pages__container > div.tabs-tab.page-sign.active > div > div.input-wrapper > button:nth-child(6) > div").click()
})
}
await page.waitForTimeout(5000)
await page.evaluate(() => {
document.querySelector("#auth-pages > div > div.tabs-container.auth-pages__container > div.tabs-tab.page-sign.active > div > div.input-wrapper > div.input-field.input-field-phone > div.input-field-input").childNodes[0].textContent = "+55 11 944407845"
document.querySelector("#auth-pages > div > div.tabs-container.auth-pages__container > div.tabs-tab.page-sign.active > div > div.input-wrapper > button.btn-primary.btn-color-primary.rp > div").click()
})
await page.waitForTimeout(30000)
const foo = await page.$x('//*[#id="column-left"]/div/div/div[1]/div[2]/input');
await foo[0].type("folio_bill_bot")
await page.waitForTimeout(5000)
const xp = `/html/body/div[1]/div[1]/div[1]/div/div/div[2]/div[2]/div[2]/div/div/div[1]/div/div[1]/ul/li/div[1]`;
const sizeButton = await page.waitForXPath(xp);
await sizeButton.evaluate(btn => {
btn.closest("li").dispatchEvent(new Event("mousedown"));
});
await page.waitForTimeout(10000);
//await Promise.all([foo2[0].click()])
//await foo2[0].click()
return [page, browser]
}
inicializar()
For those who want to look at the HTML:

Related

puppeteer-cluster, different data to the same url

i put an example below that i want to add different search inputs (firstWord + scndWord) from array of object to two google pages in the same time, so opening pages dynamically depend on the array length
1st page open google then write red flower
2nd page open google but write 'gaming PC
const { Cluster } = require('puppeteer-cluster');
(async () => {
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 10,
puppeteerOptions: {
headless: false,
},
});
cluster.on('taskerror', (err, url) => {
console.error((new Date()).toJSON() + ` Error crawling ${url}: ${err.message}`);
});
const arr = [
{firstWord: 'gaming ',scndWord: 'pc'},
{firstWord: 'red ', scndWord: 'flower'}
]
await cluster.task(async ({ page, data: index }) => {
await page.goto('https://www.google.com/');
await page.focus('body > div.L3eUgb > div.o3j99.ikrT4e.om7nvf > form > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input')
await page.keyboard.type('flower');
await page.waitForNavigation()
await page.screenshot({ path: 'screenshot.png', fullPage: true })
});
for (let index = 0; index <=arr.length -1 ; index++) {
cluster.execute(index);}
I'm confusing how to do that, i will be thankful for the help
i got it
const { Cluster } = require('puppeteer-cluster');
(async () => {
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 10,
puppeteerOptions: {
headless: false,
},
});
cluster.on('taskerror', (err, url) => {
console.error((new Date()).toJSON() + ` Error crawling ${url}: ${err.message}`);
});
const arr = [
{firstWord: 'gaming ',scndWord: 'pc'},
{firstWord: 'red ', scndWord: 'flower'}
]
await cluster.task(async ({ page, data: [firstWord , scndWord] }) => {
await page.goto('https://www.google.com/');
await page.focus('body > div.L3eUgb > div.o3j99.ikrT4e.om7nvf > form > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input')
await page.keyboard.type(firstWord + scndWord);
await page.waitForNavigation()
await page.screenshot({ path: 'screenshot.png', fullPage: true })
});
arr.map((serach)=>{
cluster.execute([serach.firstWord, serach.scndWord]);
})
// await cluster.idle();
// await cluster.close();
})();

How to solve nodejs puppeteer Cannot find module 'puppeteer' error

I have installed puppeteer
`
const automation = require("puppeteer");
const fs = require("fs");
const automationConfiguration = {
headless: false
}
async function runautomation() {
const browser = await automation.launch(automationConfiguration)
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await navigationPromise
await page.goto('https://www.google.com/search?q=perfmatters+vs+wp+rocket&oq=perf&aqs=chrome.0.69i59j69i57j0i67j46i433i512j0i433i512l2j0i131i433i512j69i64.961j0j15&sourceid=chrome&ie=UTF-8')
await page.setViewport({ width: 1366, height: 657 })
await page.waitForSelector('.MjjYud:nth-child(5) > .g > .kvH3mc > .Z26q7c > .yuRUbf > a > .LC20lb')
await page.click('.MjjYud:nth-child(5) > .g > .kvH3mc > .Z26q7c > .yuRUbf > a > .LC20lb')
await navigationPromise
await browser.close() }
runautomation()
`
I have tried everyting from my end but nothing works im new to puppeteer please help

node - How to open two tabs and run puppeteer on them

I need to fill out a form in a page with puppeteer. I have created a script that is working fine and will complete the form fields. The only problem that I'm trying to fix is that I need a working email address. What I want to do is to use tempmailo disposable email, I want to open the website inside another tab and get the generated email address from the related input field, then paste it inside the other page where the form will be filled from puppeteer and after that check if the activation email with the code is arrived. Is this possible?
I've added the code to open another page in my actual script but it will stop the form filling. Any help?
#!/usr/bin/env node
process = require('process');
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('5xxxx', {polling: true});
const Puppeteer = require('puppeteer');
const { faker } = require('#faker-js/faker');
let newAccounts = Array;
let igAccountToIncrease = String;
let requiredFollowers = Number;
let email = String;
bot.onText(/\/add (.+)/, async (message, match) => {
const browser = await Puppeteer.launch({
headless: false,
slowMo: 300,
devtools: true,
});
const page = await browser.newPage();
await page.goto('https://www.example.com/accounts/emailsignup/');
await page.setViewport({ width: 1280, height: 607 });
await page.waitForSelector('body > .RnEpo > .pbNvD > ._1XyCr > .HoLwm')
await page.click('body > .RnEpo > .pbNvD > ._1XyCr > .HoLwm')
// after this line the script will stop filling the form and will only open the new tab
const emailPage = await browser.newPage()
const navigationPromise = emailPage.waitForNavigation()
await emailPage.goto('https://tempmailo.com/')
await emailPage.setViewport({ width: 1280, height: 607 })
await emailPage.waitForSelector('#i-email')
await emailPage.click('#i-email')
email = await emailPage.$eval('#i-email', (input) => {
return input.getAttribute('value');
});
await page.waitForSelector('input[name=emailOrPhone]')
await page.click('input[name=emailOrPhone]')
await page.type('input[name=emailOrPhone]', email, {
delay: 100
});
await page.waitForSelector('input[name=fullName]')
await page.click('input[name=fullName]')
const name = faker.name.findName();
await page.type('input[name=fullName]', name, {
delay: 100
});
console.log(name);
await page.waitForSelector('input[name=username]')
await page.click('input[name=username]')
const username = faker.internet.userName(name);
await page.type('input[name=username]', username, {
delay: 100
});
console.log(username);
await page.waitForSelector('input[name=password]')
await page.click('input[name=password]')
await page.type('input[name=password]', '1234564abc', {
delay: 100
})
await page.waitForSelector('.P8adC > .XFYOY > div > .qF0y9 > .sqdOP')
await page.click('.P8adC > .XFYOY > div > .qF0y9 > .sqdOP')
await page.waitForSelector('div > .qF0y9 > span > .O15Fw:nth-child(1) > .h144Z')
await page.click('div > .qF0y9 > span > .O15Fw:nth-child(1) > .h144Z')
await page.select('div > .qF0y9 > span > .O15Fw:nth-child(1) > .h144Z', '4')
await page.waitForSelector('div > .qF0y9 > span > .O15Fw:nth-child(2) > .h144Z')
await page.click('div > .qF0y9 > span > .O15Fw:nth-child(2) > .h144Z')
await page.select('div > .qF0y9 > span > .O15Fw:nth-child(2) > .h144Z', '25')
await page.waitForSelector('div > .qF0y9 > span > .O15Fw:nth-child(3) > .h144Z')
await page.click('div > .qF0y9 > span > .O15Fw:nth-child(3) > .h144Z')
await page.select('div > .qF0y9 > span > .O15Fw:nth-child(3) > .h144Z', '1989')
await page.waitForSelector('.rgFsT > .gr27e > .qF0y9 > .qF0y9:nth-child(7) > .sqdOP')
await page.click('.rgFsT > .gr27e > .qF0y9 > .qF0y9:nth-child(7) > .sqdOP')
await page.waitForSelector('.qF0y9 > form > .qF0y9 > .qF0y9 > .j_2Hd')
await page.click('.qF0y9 > form > .qF0y9 > .qF0y9 > .j_2Hd')
});
The website with the form is made with react, the second one with Vue.

Puppeteer eval issues

I am having issues trying to get this to work.
I am needing to select the calendar heading "May 2020", but am not having any luck, could I get someone to look at what I am doing wrong?
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.stayz.com.au/holiday-rental/p9177051?noDates=true',{waitUntil: 'domcontentloaded'});
const headingTxt = await page.evaluate(() =>
document.querySelector('#rates-availability > div > div > section > div > div.inline-calendar > div > div.cal-controls__calendar-parent--middle-multi > div > div:nth-child(2) > h4 > span').innerText);
console.log('');
console.log('========[ output ]======== ', headingTxt);
console.log('');
await page.close();
await browser.close();
})();
This selector needs scrolling and wide viewport to appear:
'use strict';
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false, args: ['--start-maximized'] }); //
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 850 });
await page.goto('https://www.stayz.com.au/holiday-rental/p9177051?noDates=true', {waitUntil: 'domcontentloaded'});
const selector = '#rates-availability > div > div > section > div > div.inline-calendar > div > div.cal-controls__calendar-parent--middle-multi > div > div:nth-child(2) > h4 > span';
while ((await page.$(selector)) === null) {
await page.evaluate(() => { window.scrollBy(0, window.innerHeight); });
await page.waitFor(1000);
}
const headingTxt = await page.evaluate(
selector => document.querySelector(selector).innerText,
selector
);
console.log('');
console.log('========[ output ]======== ', headingTxt);
console.log('');
await page.close();
await browser.close();
})();

How to get an attribute value from html node <a>?

I am trying to scrape the website below and I am not getting the value of the attribute 'data-link'.
http://www.apptrace.com/itunes/charts/FRA/topfreeapplications/36/2018-12-27
Could someone help me?
//attempt #1 (error)
const puppeteer = require('puppeteer')
let scrape = async () => {
const browser = await puppeteer.launch({headless: true})
const page = await browser.newPage()
await page.goto('http://www.apptrace.com/itunes/charts/USA/topfreeapplications/36')
await page.waitFor(1000)
const countryCharts = await page.evaluate(() => {
const abbrAppsCountry = []
document.getElementById('#current_storefront_list')
.getAttribute('li > a[data-link]')
.forEach(app => abbrAppsCountry.push(app.value))
return abbrAppsCountry
})
browser.close()
return countryCharts
}
scrape().then((value) => {
console.log(value)
})
//attempt #2 (array of nulls)
const puppeteer = require('puppeteer')
let scrape = async () => {
const browser = await puppeteer.launch({headless: true})
const page = await browser.newPage()
await page.goto('http://www.apptrace.com/itunes/charts/USA/topfreeapplications/36')
await page.waitFor(1000)
const countryCharts = await page.evaluate(() => {
const abbrAppsCountry = []
document.querySelectorAll('#current_storefront_list > li > a[data-link]')
.forEach(app => abbrAppsCountry.push(app.value))
return abbrAppsCountry
})
browser.close()
return countryCharts
}
scrape().then((value) => {
console.log(value)
})
I would like to get the abbreviation of country names.
You can use dataset or getAttribute APIs:
document.querySelectorAll('#current_storefront_list > li > a')
.forEach(app => abbrAppsCountry.push(app.dataset.link))
Or:
document.querySelectorAll('#current_storefront_list > li > a')
.forEach(app => abbrAppsCountry.push(app.getAttribute('data-link')))

Categories

Resources