puppeteer writing in the label doesn't work pop up - node.js

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();
})();

Related

How to login to google account with playwright?

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']
})

How to trigger "Followers" modal on Instagram?

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();
})();
}

Unable to login with Puppeteer

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();
})();

Running a loop within an instance of Puppeteer

Just getting started with Puppeteer and i can launch the browser, go to a url, run a bunch of actions and then close the browser. What i am looking to see if i can do though is open the browser and loop over a set of actions in the same session.
I have a JSON object with urls i want to visit, so want to loop over that
// teams.js
module.exports = {
premier_league: [
{ team_name: "Team 1", url: "https://url-of-site/team_1"},
{ team_name: "Team 2", url: "https://url-of-site/team_2"}
]
}
My script to launch puppeteer is as follows
// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');
(async () => {
// Initialise Browser
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
await page.goto('login page');
await page.click('login_box');
await page.keyboard.type('username');
await page.click('login_password');
await page.keyboard.type('password');
await page.click('login_button');
await page.waitForNavigation();
// Go To Team URL
await page.goto('Team URL')
await browser.close();
})();
So to loop over my JSON object I can use
Object.keys(TEAM['premier_league']).forEach(function(key) {
// Output url of each team
console.log(TEAM['premier_league'][key]['url'])
});
If i wrap my go to url with my loop, then page is no longer accessible
// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');
(async () => {
// Initialise Browser
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
await page.goto('login page');
await page.click('login_box');
await page.keyboard.type('username');
await page.click('login_password');
await page.keyboard.type('password');
await page.click('login_button');
await page.waitForNavigation();
Object.keys(TEAM['premier_league']).forEach(function(key) {
// Go To Team URL
await page.goto(TEAM['premier_league'][key]['url'])
});
await browser.close();
})();
The actual error is
await page.goto(TEAM[args][key]['url'])
^^^^
SyntaxError: Unexpected identifier
Your Object.keys callback function need to use async as well in order to use await inside. Try to change as below
Object.keys(TEAM['premier_league']).forEach( async function(key) {
// Go To Team URL
await page.goto(TEAM['premier_league'][key]['url'])
});
Hope it helps

Node puppeteer take screenshot full page SPA

I have a single page application with scrolling. I am trying to take a screenshot of the whole page, but it only gives me the visible part. How can I make it shoot the whole page?
const browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.goto(url);
await page.screenshot({ path: 'page.png', fullPage: true })
await browser.close();
Actually what is happening here that your page might took a while to load in full. So we have to increase the timeout. And before taking screen shot take a short break of 500ms and then it will take full page screenshot. Try below code.
const puppeteer = require('puppeteer');
async function runTest() {
const browser = await puppeteer.launch({
headless: false,
timeout: 100000
});
const page = await browser.newPage();
const url = 'https://stackoverflow.com/questions/47616985/node-puppeteer-take-screenshot-full-page-spa';
await page.goto(url, {
waitUntil: 'networkidle2'
});
await page.waitFor(500);
await page.screenshot({ path: 'fullpage.png', fullPage: true });
browser.close();
}
runTest();
Your code looks correct. What are you passing in options?
Is the page actually launching? Try turning off headless browser to check:
const browser = await puppeteer.launch({
headless: false
});
The following works for me to take a full page screenshot:
const puppeteer = require('puppeteer');
async function run() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://yahoo.com');
await page.screenshot({ path: 'yahooPage.png', fullPage: true });
browser.close();
}
run();

Resources