我需要得到一个表中的每一个客户端,这样我就可以迭代它们,并使用Puppeteer来抓取一些数据。我需要MySQL查询,因为我必须通过查询字符串传递一些参数。
我使用的是Puppeteer,Puppeteer集群(由于数百行)和MySQL驱动程序。
const mysql = require('mysql');
const { Cluster } = require('puppeteer-cluster');
const sql = "select an.id_clientes, ano, c.nome, c.cpf, c.dt_nasc from clientes_anos an inner join clientes c on an.id_clientes = c.id limit 3";
db.query(sql, async (err, result) => {
//console.log(result);
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_CONTEXT,
maxConcurrency: 2,
puppeteerOptions: {
headless: false
},
//monitor: true,
timeout: 90000,
});
for (const elem of result){
const cpf = elem.cpf;
const dt = elem.dt_nasc.toLocaleDateString();
const url = `https://servicos.receita.fazenda.gov.br/Servicos/ConsRest/Atual.app/paginas/index.asp?cpf=${cpf}&dtnasc=${dt}`;
console.log(url);
(async()=>{
cluster.on('taskerror', (err, data) => {
//console.log(`Error crawling ${data}: ${err.message}`);
});
await cluster.task(async ({ page, data: url }) => {
console.log(dt, cpf);
await page.goto(url);
await page.type('#data_nascimento', dt);
await page.type('input[name=CPF]', cpf);
await page.waitForNavigation();
try{
const msg = await page.$eval(
`#rfb-main-container table tbody tr:nth-of-type(1) td:nth-of-type(1)`, divs => divs.innerText.trim()
);
if(msg.includes('Resultado encontrado: Saldo inexistente de imposto a pagar ou a restituir.')){
console.log('situação: '+ msg);
}else{
console.log('0');
}
}catch(exception){
console.log('Error');
}
});
await cluster.queue(url);
await cluster.idle();
await cluster.close();
})();
}
});我遇到的问题是,当页面加载时,await page.type('#data_nascimento', dt); await page.type('input[name=CPF]', cpf);没有返回正确的值(来自查询的值是正确的),而是返回最后一行的值。我打赌这是有异步的东西,但我想不出来。
我有什么办法解决这个问题吗?
发布于 2021-05-21 22:37:41
该死的孩子,我有话要说
上的观点
for (var i = 0; i<3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
// shows : 3 3 3
// because when console is finally executed "i" has been fully looped如果您没有使用var,而是使用了const或let,代码就可以正常工作,并显示0 1 2。
如果您不使用回调,而只是等待,这种情况将更加清楚。
async function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
for (var i = 0; i<3; i++) {
await wait(1000);
console.log(i);
}您可以将此应用于mysql调用,以使代码扁平化。
function query(sql) {
return new Promise((resolve, reject) => {
db.query(sql, function(err, result) {
if (err) return reject(err);
resolve(result);
})
});
}
//then you call it like this
const sql = "select an.id_clientes, ano, c.nome, c.cpf, c.dt_nasc from clientes_anos an inner join clientes c on an.id_clientes = c.id limit 3";
const result = await query(sql)“
)中推送。
cluster.queue(XXX)
=>
await cluster.task(async ({ page, data: XXX}) ...)然后,如果您需要许多不同的数据,那么您不仅应该推送您的url,还应该推送整个对象。
cluster.queue({cpf, dt, url})
=>
await cluster.task(async ({ page, data: {cpf, dt, url}}) ...)我从未试过使用这个模块,但它对我来说很有意义。你能试试吗?
PS:而且,根本不使用集群可以大大简化事情。
https://stackoverflow.com/questions/67644228
复制相似问题