cloudflare-demo
cloudflare-demo copied to clipboard
AWS Lambda + Puppeteer endless loop
Issue
When using Puppeteer in AWS Lambda and attempting to solve the Cloudflare captcha, it seems to go into an endless loop of being solved. The Cloudflare page resets, and then it starts solving again.
I've tried using proxies for Puppeteer, thinking it may be IP related, but the same result happens.
Here is a screenshot of what my CloudWatch logs show. The correct params are being intercepted, and I get a response back from 2captcha with a token to use for the cfCallback, but then the page seems to reload after that.
Code Example
import { Solver } from '2captcha-ts';
import puppeteerExtra from 'puppeteer-extra';
import pluginStealth from 'puppeteer-extra-plugin-stealth';
export async function handler() {
const viewport = {
deviceScaleFactor: 1,
hasTouch: false,
height: 1080,
isLandscape: true,
isMobile: false,
width: 1920
};
const puppeteerExtraDefault = puppeteerExtra.default;
puppeteerExtraDefault.use(pluginStealth());
const args = chromium.args;
const browser = await puppeteerExtraDefault
.launch({
args: args,
defaultViewport: viewport,
executablePath: await chromium.executablePath(),
headless: 'shell'
});
console.log('browser loaded');
const [page] = await browser.pages();
page.on('console', (msg) => {
console.log('[PAGE LOG]', msg.text());
});
await page.evaluateOnNewDocument(`
console.log('Script being injected');
console.clear = () => console.log('Console was cleared')
const i = setInterval(() => {
if (window.turnstile) {
clearInterval(i)
window.turnstile.render = (a, b) => {
let params = {
sitekey: b.sitekey,
pageurl: window.location.href,
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent,
json: 1
}
// we will intercept the message in puppeeter
console.log('intercepted-params:' + JSON.stringify(params))
window.cfCallback = b.callback
return
}
}
}, 50)
`);
await page.setUserAgent(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
);
const userAgent = await page.evaluate(() => navigator.userAgent);
console.log('Current user agent:', userAgent);
const solver = new Solver('mySuperSecretKey');
// Here we intercept the console messages to catch the message logged by inject.js script
page.on('console', async (msg) => {
const txt = msg.text()
if (txt.includes('intercepted-params:')) {
const params = JSON.parse(txt.replace('intercepted-params:', ''))
console.log(params)
try {
console.log(`Solving the captcha...`)
const res = await solver.cloudflareTurnstile(params)
console.log(`Solved the captcha ${res.id}`)
console.log(res)
await page.evaluate((token) => {
// @ts-ignore
cfCallback(token)
}, res.data)
} catch (e) {
console.log(e.err)
return process.exit()
}
} else {
return;
}
})
await page.goto('https://2captcha.com/demo/cloudflare-turnstile-challenge')
// Wait for a total of 45 seconds for the page to load
try {
await page.waitForSelector('#root > div._layout_1smur_1', { timeout: 45000 });
} catch (e) {
console.error('Error waiting for the page to load:', e);
await browser.close();
return;
}
console.log('Page loaded successfully');
await browser.close();
return '';
}