Twitter Puppeteer - how to click elements - node.js

Hello I'm trying join twitter via puppeteer to twitter, sign up via gmail.
But I'm facing objects I see by inspect aren't visible source of page, and I don't understand.
Here is example of code:
async function twitter(browserID) {
const browserData = await getProfileData(browserID);
const port = browserData.automation.port;
const wsEndpoint = browserData.automation.wsEndpoint;
// temp
// let port = "52654";
// let wsEndpoint = "/devtools/browser/7e7701c5-64c1-4d32-be9a-6198c58d58ae";
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://127.0.0.1:${port}${wsEndpoint}`,
});
const page = await browser.newPage();
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
});
await page.goto('https://twitter.com', { waitUntil: 'networkidle2' });
await sleep(5000);
await page.click('span[class^="nsm7Bb-HzV7m-LgbsSe-"]');
await sleep(3000);
};
I've fixed issue:
await page.goto('https://twitter.com');
await sleep(3000);
const frame = page.frames().find(f => f.url().startsWith('https://accounts.google.com/gsi/button'));
const acceptBtn = await frame.$('#container > div > div.nsm7Bb-HzV7m-LgbsSe-bN97Pc-sM5MNb.oXtfBe-l4eHX > span.nsm7Bb-HzV7m-LgbsSe-BPrWId');
await acceptBtn.click();

Related

Puppeter dont make right click in all links

I am trying to do right click in all links in a page but is not working. I want to do right click because i have to test some events for mousedown, so i dont have to do necesarily click on them. I use right click so the links dont reload the page o redirect
(async () => {
const url = 'yourUrlHere';
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(url);
// test1
const elHandleArray = await page.$$('a');
for (const el of elHandleArray) {
console.log('### Clicking...' + el);
await el.evaluate(b => b.click({ button: "right", }));
//await el.click({ button: "right" });
}
// test2
await page.evaluate(() => {
const elHandleArray = document.querySelectorAll('a');
for (const el of elHandleArray) {
console.log('### Clicking...' + el);
el.click({ button: "right" });
}
});
// test3
const aElems = await page.$$('a');
for (let i = 0; i < aElems.length; i++) {
const elem = aElems[i];
console.log('### Click element: ', i);
await page.waitForTimeout(elem);
await page.evaluate((e) => {
document.querySelector(e).click({ button: "right", });
}, elem);
}
})();

Is there a way to msg this daily ? Discord.Js

Is there a way to add command so bot will message this command everday in custom channel on server? Its for CS:GO Matches statistics
const BaseCommand = require('../../utils/structures/BaseCommand');
const Discord = require("discord.js");
const puppeteer = require('puppeteer');
module.exports = class LinkCommand extends BaseCommand {
constructor() {
super('mec', 'fun', []);
}
async run(client, message, args) {
const browser = await puppeteer.launch({defaultViewport: null});
const page = await browser.newPage();
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
});
await page.setDefaultNavigationTimeout(0);
await page._client.send('Network.getAllCookies');
await page.goto('https://pro.eslgaming.com/csgo/proleague/schedule/#?matchday=2');
console.log(await page.content());
await page.screenshot({path: 'screenhhhhshot.png'});
let screenshot = await page.screenshot();
await browser.close();
let today = new Date().toISOString().slice(0, 10)
message.channel.send(`${today}`, {files: [screenshot]});
message.delete();
}
}
What i want to do like to set command that will everyday make bot to send message in custom channel on discord server
I got it
setInterval(() => {
message.channel.send(`${today}`, {files: [screenshot]});
message.delete();
}, 60000);
at the end 60000 is milliseconds just change that to 24h into milliseconds and boom :D

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

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

Resources