I am automating some image downloads using puppeteer Js.
While I am triggering the download button it shows the save As prompt window.
is there any way to disable it or accept it using puppeteer?
Check the below code.
Before clicking the Download Button, We can set the Download Behaviour of the Client when launching the Browser Instance. This way you don't have to click on the Save As button.
await page._client.send("Page.setDownloadBehavior", {
behavior: "allow",
downloadPath: downloadPath,
});
Here is the Complete code:
const puppeteer = require("puppeteer");
const path = require("path");
const downloadPath = path.resolve("./download");
async function fileDownload() {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto("https://unsplash.com/photos/_jHJce5uI7I", {
waitUntil: "networkidle2",
});
await page._client.send("Page.setDownloadBehavior", {
behavior: "allow",
downloadPath: downloadPath,
});
await page.click(".wl5gA ");
}
fileDownload();
It creates a directory called download based on the path I have given.
Related
I am trying to make a scraper that gets the reviews for hotel on tripadvisor.com. I was just working with pagination and testing if the browser would go all the way to the end, where there is no more pages.
Here is my code so far:
const puppeteer = require("puppeteer");
const cheerio = require("cheerio");
async function main() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://www.tripadvisor.com/Hotels-g298656-Ankara-Hotels.html');
while(true) {
await page.click('a[class="nav next ui_button primary"]');
await page.waitForNavigation({waitUntil: 'networkidle0'});
}
}
main();
However, this stops when the 'accept cookies' popup appears. How can I handle this?
I'm trying to open a new window page from a button in Puppeteer.
An example given: I'm logging to a website and the moment I click the button for the login a new fresh window page will pop-up, redirecting to the site the button is meant to be going. How can I do it?
You can do that by simply pressing Shift button while doing page.click
And to catch the newly opened window you can use waitForTarget.
const puppeteer = require('puppeteer')
;(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
})
const context = browser.defaultBrowserContext()
const page = (await context.pages())[0]
await page.goto('https://www.amazon.com/gp/product/B093GQSVPX/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1', {waitUntil: 'load'})
await page.waitForSelector('a[title="Add to List"]', {visible: true})
await page.keyboard.down('Shift')
await page.click('a[title="Add to List"]')
await page.keyboard.up('Shift')
const popup = await browser.waitForTarget(
(target) => target.url().includes('www.amazon.com/ap/signin')
)
const popupPage = await popup.page()
await popupPage.waitForSelector('a.a-link-expander[role="button"]')
await popupPage.click('a.a-link-expander[role="button"]')
await popupPage.click('input#continue[type="submit"]')
await browser.close()
})()
I originally wanted to launch a Puppeteer instance for each unique profile I had. I managed to figure this out but a new problem has come up. Basically, in one point of my script I tell the browser to close the tab and reopen a new one. It closes each tab in each individual browser fine but when I use await browser.newPage(); it sends all the new tabs to just one browser (which I'm guessing was the last browser opened) instead of staying in their respective browser.
const puppeteer = require('puppeteer-extra');
const fs = require('fs');
const botRun = async emailInfo => {
browser = await puppeteer.launch({
args: [],
headless: false,
ignoreHTTPSErrors: true,
slowMo: 5,
});
const page = await browser.newPage();
await page.waitForTimeout(2500)
// do stuff with emailInfo
await page.close(); // works fine - will close tab for each browser
await browser.newPage(); // suddenly sends all tabs to 1 browser
};
(async () => {
const profile = JSON.parse(fs.readFileSync("./settings.json"));
await Promise.all(profile.map(({email}) => botRun(email)));
})();
settings.json looks like:
[
{"email": "email1#gmail.com"},
{"email": "email2#gmail.com"},
{"email": "email3#gmail.com"}
]
Is there any workaround for this?
I use the following blog to use the playright
login and I need something similar to use for my app, when I use the headless:flase
I see it opens the UI with the user password in however, it doesnt click on the logon button, I adopt the code I try with the following , am I missing something?
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://app.com');
await page.fill('input[type="text"]', 'user#test.com');
await page.fill('input[type="password"]', 'Abcd1234!');
// page.click('div[data-testid="LoginForm_Login_Button"]');
page.click('div[id="logOnFormSubmit"]');
}
)();
You are currently using
page.click('div[id="logOnFormSubmit"]');
There is no div in your given code example with that ID, but instead there is a button. You'd need to change that line to reflect this. The final code would look like below.
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://app.com');
await page.fill('input[type="text"]', 'user#test.com');
await page.fill('input[type="password"]', 'Abcd1234!');
// page.click('div[data-testid="LoginForm_Login_Button"]');
page.click('button[id="logOnFormSubmit"]');
}
)();
I am trying to grab some html after a input tag button is clicked. I am clicking the button with page.evaluate() since page.click() does not seem to work for an input tag button. I have tried visual debugging with headless:false in the puppeteer launch options to verify that the browser indeed navigated to the point after the button is clicked. I am unsure as to why page.content() returns the html before the button is clicked rather than the html after the event happens.
const puppeteer = require('puppeteer');
const url = 'http://www.yvr.ca/en/passengers/flights/departing-flights';
const fs = require('fs');
const tomorrowSelector = '#flights-toggle-tomorrow'
puppeteer.launch().then(async browser => {
const page = await browser.newPage();
await page.goto(url);
await page.evaluate((selector)=>document.querySelector(selector).click(),tomorrowSelector);
let html = await page.content();
await fs.writeFile('index.html', html, function(err){
if (err) console.log(err);
console.log("Successfully Written to File.");
});
await browser.close();
});
You can click on the label for the radio. Also, you need to wait for some sign of changed state (for XHR/fetch response or new selectors). For example, this code works for me, but you can use any other condition or just wait for some seconds.
const fs = require('fs');
const puppeteer = require('puppeteer');
const url = 'http://www.yvr.ca/en/passengers/flights/departing-flights';
const tomorrowLabelSelector = 'label[for=flights-toggle-tomorrow]';
const tomorrowLabelSelectorChecked = '.yvr-form__toggle:checked + label[for=flights-toggle-tomorrow]';
puppeteer.launch({ headless: false }).then(async (browser) => {
const page = await browser.newPage();
await page.goto(url);
await Promise.all([
page.click(tomorrowLabelSelector),
page.waitForSelector(tomorrowLabelSelectorChecked),
]);
const html = await page.content();
await fs.writeFile('index.html', html, (err) => {
if (err) console.log(err);
console.log('Successfully Written to File.');
});
// await browser.close();
});