I have this puppeteer code:
(async () => {
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto("https://myurl.com/page");
await page.waitForSelector("#select-all-checkbox");
var bodyHTML = await page.content();
console.log(bodyHTML + "\n\n");
await page.click("#select-all-checkbox");
await page.close();
await browser.close();
})();
Logging the HTML to the console, I have verified the page I am accessing has this HTML:
<label><input type="checkbox" name="" id="select-all-checkbox" value="" checked=""><span class="ifaFs"><span data-testid="icon-checkbox-someselected" class="hdDWuD"></span></span></label>
I am receiving this error on the page.click line:
(node:3827) UnhandledPromiseRejectionWarning: Error: Node is either
not visible or not an HTMLElement
at ElementHandle._clickablePoint (/path/to/node_modules/puppeteer/lib/JSHandle.js:217:13)
at process._tickCallback (internal/process/next_tick.js:68:7)
-- ASYNC --
at ElementHandle. (/path/to/node_modules/puppeteer/lib/helper.js:111:15)
at DOMWorld.click (/path/to/node_modules/puppeteer/lib/DOMWorld.js:367:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
-- ASYNC --
at Frame. (/path/to/node_modules/puppeteer/lib/helper.js:111:15)
at Page.click (/path/to/node_modules/puppeteer/lib/Page.js:1037:29)
With my code example above, this was how I resolved the problem.
(async () => {
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto("https://myurl.com/page");
await page.waitForSelector("#select-all-checkbox");
await page.evaluate(() => {
document.querySelector("#select-all-checkbox").parentElement.click();
});
await page.close();
await browser.close();
})();
This approach worked for me:
(async () => {
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto("https://myurl.com/page");
const checkboxEl = await page.waitForSelector("#select-all-checkbox");
checkboxEl.click();
await page.close();
await browser.close();
})();
Related
I am trying to log in to our company's Runscope tests page. My code
const puppeteer = require('puppeteer');
const C = require('./constants');
const USERNAME_SELECTOR = '#login-email';
const PASSWORD_SELECTOR = '#login-password';
const CTA_SELECTOR = '#login-submit';
async function startBrowser() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
return { browser, page };
}
async function closeBrowser(browser) {
return browser.close();
}
async function playTest(url) {
const { browser, page } = await startBrowser();
await page.goto(url);
await page.click(USERNAME_SELECTOR);
await page.keyboard.type(C.username);
await page.click(PASSWORD_SELECTOR);
await page.keyboard.type(C.password);
await page.click(CTA_SELECTOR);
await page.waitForNavigation();
}
(async () => {
await playTest("https://www.runscope.com/ckapi/mr/36ba13e6-d2pp-477b-8149-2935fa768c29");
process.exit(1);
})();
I got this warning
(node:10040) UnhandledPromiseRejectionWarning: Error: No node found for selector: #login-email
at Object.assert (C:\Users\v-mimaliprc\runscope2\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:26:15)
at DOMWorld.click (C:\Users\v-mimaliprc\runscope2\node_modules\puppeteer\lib\cjs\puppeteer\common\DOMWorld.js:277:21)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async playTest (C:\Users\v-mimaliprc\runscope2\index.js:21:5)
at async C:\Users\v-mimaliprc\runscope2\index.js:31:5
(Use `node --trace-warnings ...` to show where the warning was created)
WHat is wrong with my code? I placed Username and Password into constants file.
You selector is probably not rendered yet. Try to use those lanes before event call:
await page.waitFor(500)
await page.waitForSelector(USERNAME_SELECTOR)
await page.click(USERNAME_SELECTOR);
...
Similar solved problem
I have following source code and run it in headful mode.
I can input email address.
But, after that, there is message that saying "Couldn't sign you in.For your protection, you can't sign in from this device. Try again later, or sign in from another device.".
Do I need to set additional header or something else?
Here is my source code.
const playwright = require('playwright');
const cookiePath = '/home/ubuntu/.config/chromium/Default';
browser['chromium'] = await playwright['chromium'].launchPersistentContext(cookiePath,{
headless: false,
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`,
],
});
const page = await browser['chromium'].newPage();
const login_url = "https://accounts.google.com/signin/v2/identifier?hl=ja&flowName=GlifWebSignIn&flowEntry=ServiceLogin";
await page.goto(login_url);
await page.fill('#identifierId',userinfo['id']);
await page.click("#identifierNext");
await page.fill('[name=password]',userinfo['password']);
await page.click("#passwordNext");
My solution:
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch({
headless: false,
args: ["--disable-dev-shm-usage"],
});
const context = await browser.newContext({});
const page = await context.newPage();
const navigationPromise = page.waitForNavigation({
waitUntil: "domcontentloaded",
});
await page.setDefaultNavigationTimeout(0);
await page.goto(
"https://accounts.google.com/signin/v2/identifier?hl=en&flowName=GlifWebSignIn&flowEntry=ServiceLogin"
);
await navigationPromise;
await page.waitForSelector('input[type="email"]');
await page.type('input[type="email"]', "youremail");
await page.click("#identifierNext");
await page.waitForSelector('input[type="password"]', { visible: true });
await page.type('input[type="password"]', "yourpassword");
await page.waitForSelector("#passwordNext", { visible: true });
await page.click("#passwordNext");
await navigationPromise;
//you are in
I think you can search for login to google with Puppeteer also.
This works for me:
add --disable-blink-features=AutomationControlled to your args.
This works for me:
const browser = await playwright.chromium.launch({
ignoreDefaultArgs: ['--disable-component-extensions-with-background-pages']
})
I'm creating a bot to enter the site.
After opening the popup I have 2 fields, emailAddress and password. Both have random id and only name value.
The emailAddress is not completing. But the password works normally(completing).
This is a part my code
//open poupup
await page.$eval( '#anchor-open', form => form.click() );
//wait for the screen to load
await page.waitForSelector('input[name="emailAddress"]');
//write in the fields
await page.type('input[name="emailAddress"]', '22#d.com', {delay: 100});
await page.type('input[name="password"]', '****************', {delay: 100});
Can someone help me?
You need to wait for domcontentloaded event. then wait for #anchor-acessar element before click it.
The code below working fine with me.
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto("https://www.nike.com.br", {
waitUntil: "domcontentloaded",
});
await page.waitForSelector('#anchor-acessar');
await page.$eval("#anchor-acessar", (form) => form.click());
await page.waitForSelector('input[name="emailAddress"]');
await page.type('input[name="emailAddress"]', "22#d.com", { delay: 100 });
await page.type('input[name="password"]', "****************", { delay: 100 });
await page.keyboard.press('Enter');
// await browser.close();
})();
I can't get my puppet to click on the "Followers" link in Instagram.
I assume that Instagram has done some anti-bot magic, but maybe I'm just too conspiratory about it.
How could I get the "Followers" modal to show?
This is my code:
const puppeteer = require('puppeteer');
var instagram = {
username: 'username',
password: 'password'
}
var run = ()=>{
(async () => {
const browser = await puppeteer.launch({headless: false, args: ['--lang=en-EN,en']});
const page = await browser.newPage();
await page.setExtraHTTPHeaders({ 'Accept-Language': 'en' });
await page.goto('https://www.instagram.com/accounts/login');
await page.waitFor(1500);
await page.click("input[type=\"text\"]")
await page.keyboard.type(instagram.username);
await page.click("input[type=\"password\"]")
await page.keyboard.type(instagram.password);
await page.click("button[type=\"submit\"]");
await page.waitForNavigation();
await page.click(".HoLwm");
await page.click(".glyphsSpriteUser__outline__24__grey_9")
await page.waitForNavigation();
await page.waitFor(2500);
await page.waitForSelector('a.-nal3');
await page.evaluate(() => document.querySelector('a.-nal3')) //does not work
//await page.click(".-nal3") //does not work
await page.waitFor(3000);
await page.waitFor(1000);
//await browser.close();
})();
}
run()
While reviewing your script I noticed that not all of your selectors are the same in my Instagram so I fixed it trying not to use exact selectors since they may change tomorrow.
But this works today (see comments on what changed in the script):
var run = ()=>{
(async () => {
const browser = await puppeteer.launch({headless: false, args: ['--lang=en-EN,en']});
const rand = function(){ return Math.floor(1000 + Math.random() * 2000) }
const page = await browser.newPage();
await page.setExtraHTTPHeaders({ 'Accept-Language': 'en' });
await page.goto('https://www.instagram.com/accounts/login');
// When you can try not to `waitFor` set periods of time
// Wait for selectors, wait for random periods of time
await page.waitForSelector('button[type=\"submit\"]');
await page.click("input[type=\"text\"]")
await page.keyboard.type(instagram.username);
await page.waitFor(rand())
await page.click("input[type=\"password\"]")
await page.keyboard.type(instagram.password);
await page.waitFor(rand())
await page.click("button[type=\"submit\"]");
await page.waitForNavigation();
await page.waitFor(rand())
// After login we're back on the main page
// Wait till React starts and paints the interface
// We're waiting for "Profile" icon to be visible
await page.waitForSelector("span[aria-label='Profile']");
// Then we click on the link inside of which the icon is located
// That is link to the profile
await page.evaluate(() => document.querySelector("span[aria-label='Profile']").parentNode.click() );
await page.waitForNavigation();
await page.waitFor(rand())
// Do not rely on a selector
// Find a link that contains "followers" in its href
await page.waitForSelector("a[href*='followers']");
const followers = await page.evaluate(() => document.querySelector("a[href*='followers']").textContent)
console.log("Total followers: " + followers);
// Click on the followers link
await page.evaluate( () => document.querySelector("a[href*='followers']").click() )
// Wait for the followers modal and profiles
await page.waitFor("div[role='presentation'] div[role='dialog'] div:nth-child(2) ul li");
// Get followers that are in the list in the second div of that modal
const people = await page.evaluate(() => {
return [...document.querySelectorAll("div[role='presentation'] div[role='dialog'] div:nth-child(2) ul li")]
.map(user => {
const profLink = user.querySelector("a[title]")
return {
"name" : profLink.textContent,
"url" : profLink.href
};
})
})
console.log(people)
// await browser.close();
})();
}
I am trying to login to Moz at https://moz.com/login with Puppeteer using the following code:
const puppeteer = require('puppeteer');
const creds = {
email: "myemail",
password: "mypassword"
};
(async () => {
const browser = await puppeteer.launch({
args: [
'--disable-web-security',
],
headless: false
});
const page = await browser.newPage();
await page.goto("https://moz.com/login");
await page.$eval("input[name=email]", (el, value) => el.value = value, creds.email);
await page.$eval("input[name=password]", (el, value) => el.value = value, creds.password);
await Promise.all([
page.$eval("input[type=submit]", elem => elem.click()),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
await browser.close();
})();
I know that the email and password I am passing are correct, because I can use them to login manually, but when I run the script above, I get an "Invalid email or password" error above the form.
There are two errors logged to the JS console in Chrome:
Failed to load resource: the server Failed to load resource: the server responded with a status of 404 ()
cs.moz.com/id?d_visid_ver=1.10.0&d_fieldgroup=A&mcorgid=2C702C1653CF9B460A490D4B%40AdobeOrg&mid=86471825972219878023490878783607186756&ts=1564059866100:1
and
Failed to load resource: the server responded with a status of 400 () svc/forge/forms/login:1
Any ideas as to what the issue could be?
This error occurred because you are setting email and password by executing a javascript function $eval instead of the type function.
Also, I would suggest using the click function instead of the $eval function. Read more about the difference between a "trusted" and "untrusted" input event
just replace these lines:
await page.$eval("input[name=email]", (el, value) => el.value = value, creds.email);
await page.$eval("input[name=password]", (el, value) => el.value = value, creds.password);
with these:
await page.type('input[name=email]', creds.email);
await page.type('input[name=password]', creds.password)
So your final script should be:
const puppeteer = require('puppeteer');
const creds = {
email: "myemail",
password: "mypassword"
};
(async () => {
const browser = await puppeteer.launch({
args: [
'--disable-web-security',
],
headless: false
});
const page = await browser.newPage();
await page.goto("https://moz.com/login");
await page.type('input[name=email]', creds.email);
await page.type('input[name=password]', creds.password)
await Promise.all([
page.click('input[type=submit]'),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
await browser.close();
})();