hre*_*tic 0 javascript node.js puppeteer
即时通讯使用nodejs / puppeteer将我的用户登录到远程网站...这是它的工作方式
客户端通过socket.io连接到nodejs服务器,客户端发送start_tunnel到nodejs服务器以启动puppeteer和run(socket , data.token );运行该puppeteer的节点调用
io.on('connection' , function(socket){
socket.on('start_tunnel' , function (data) {
fullfillCaptcha[socket.id] = null ;
set_stat(socket.id , 1 );
run(socket , data.token );
})
socket.on('get_captcha_from_client' , function (data) {
fullfillCaptcha[socket.id](data);
})
});
var fullfillCaptcha = {};
var pay_stats = {} ;
function captchaPromise(id){
return new Promise(resolve => fullfillCaptcha[id] = resolve);
}
Run Code Online (Sandbox Code Playgroud)
这是给run木偶吃午餐的功能...。我已经注释了代码,因此其易于阅读...基本上,它打开了一个包含带有验证码的表单的网页,从验证码图像中获取屏幕截图,并将其发送给客户端,接收从客户端输入验证码,将其放入输入中并提交表单
async function run(socket , token ) {
/// OPENING THE WEB PAGE
const browser = await puppeteer.launch({headless: true , args:['--no-sandbox']});
const page = await browser.newPage();
await page.goto('http://example.com/init/' + token );
await Promise.race([
page.waitForNavigation(),
page.waitForSelector(".Error")
]);
/// CHECKING FOR ERROR
if (await page.$(".Error"))
{
socket.emit('payment_connection_error' );
set_stat(socket.id , 4 );
browser.close();
return ;
}
/// TAKING SCREENSHOT FROM CAPTCHA IMAGE
console.log( ' current url ' + page.url() );
let element = await page.$('#security');
await element.screenshot({path: 'public_html/captcha/'+ socket.id+'.png' });
set_stat(socket.id , 2 );
/// SENDING CAPTCHA IMAGE FOR CLIENT
socket.emit('send_captcha_to_client' , {text : socket.id+'.png' });
/// WAITING FOR CLIENT TO TYPE THE CAPTCHA AND SEND IT BACK TO SERVER
var captcha = await captchaPromise(socket.id);
if( typeof(captcha.W_CAPTCHA) == 'undefined' || captcha.W_CAPTCHA == 'cancel' )
{
console.log('canceling ... ');
set_stat(socket.id , 3 );
browser.close();
return ;
}
console.log( ' captcha confirm -> ' + captcha.W_CAPTCHA );
set_stat(socket.id , 3 );
/// TYPING CAPTCHA IN THE INPUT AND SUBMITTING THE FORM
await page.$eval('#CAPTCHA', (el , _captcha) => el.value = _captcha.W_CAPTCHA , captcha );
await page.click('#doPay');
/// CHECKING FOR SUCCESS OR ERROR OF FORM AFTER
await Promise.race([
page.waitForNavigation(),
page.waitForSelector(".Error")
]);
if (await page.$(".Error"))
{
const pay_error = await page.$eval('.Error', (element) => {
return element.innerHTML
});
console.log(" error : " + pay_error )
socket.emit('payment_error' , {text : pay_error });
}
else
{
console.log('all ok') ;
await page.click('#doSubmitTop');
await page.waitForSelector('#payment-result');
console.log( ' current url ' + page.url() );
socket.emit('payment_result');
}
browser.close();
}
Run Code Online (Sandbox Code Playgroud)
这是问题所在,由于缺少RAM及其使用ram的所有伪程序,我们有很多服务器崩溃……我们有一个不错的vps(4G RAM,2 CPU)……并且当我们在那里进行测试时可以看到服务器负载不大
所以我想知道是不是在这里做错什么,还是有什么地方可以查看日志或什么地方可以看到哪里出了问题?
Puppeteer的内存崩溃经常发生。有些页面甚至可能消耗GB的内存,因此很难预测您可以并行运行多少个实例。
如果您运行的是我期望的多个Puppeteer浏览器实例,那么很容易用很少的标签打开内存。
一些使Puppeteer的使用效率更高的内存的方法:
为了确保Puppeteer不会杀死其他进程,您可以使用有限的资源在docker容器中运行它。
我们使用此类https://github.com/apifytech/apify-js/blob/master/src/autoscaled_pool.js根据容器中的可用内存(运行接近100%CPU和100%内存)自动缩放Puppeteer任务尽可能)。