✨ feat(picc): 优化增量爬取逻辑,增加网络连接测试,设置每天9点执行增量爬取
This commit is contained in:
parent
3cce44351f
commit
91e44f5cf3
132
picc.js
132
picc.js
|
|
@ -30,6 +30,7 @@ class PICC {
|
||||||
await this.fullFetch();
|
await this.fullFetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全量爬取
|
// 全量爬取
|
||||||
async fullFetch() {
|
async fullFetch() {
|
||||||
console.log(`${this.key}-开始全量爬取...`);
|
console.log(`${this.key}-开始全量爬取...`);
|
||||||
|
|
@ -58,23 +59,85 @@ class PICC {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${this.key}-数据库操作失败:`, error);
|
console.error(`${this.key}-数据库操作失败:`, error);
|
||||||
}
|
}
|
||||||
|
// 全量爬取完成后,开始增量爬取
|
||||||
|
this.increment();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${this.key}-全量爬取失败:`, error);
|
console.error(`${this.key}-全量爬取失败:`, error);
|
||||||
}
|
}
|
||||||
console.log(`开始增量爬取...-${this.key}`);
|
|
||||||
this.increment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 增量爬取
|
// 增量爬取
|
||||||
async increment() {
|
async increment() {
|
||||||
console.log(`${this.key}-开始增量爬取模式,每5分钟检查一次新数据...`);
|
console.log(`${this.key}-开始增量爬取模式,每天9点检查一次新数据...`);
|
||||||
|
|
||||||
|
// 计算到明天9点的时间间隔
|
||||||
|
const now = new Date();
|
||||||
|
const nextRun = new Date();
|
||||||
|
nextRun.setHours(9, 0, 0, 0); // 设置为今天的9点
|
||||||
|
|
||||||
|
// 如果当前时间已经过了今天的9点,则设置为明天的9点
|
||||||
|
if (now > nextRun) {
|
||||||
|
nextRun.setDate(nextRun.getDate() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeUntilNextRun = nextRun - now;
|
||||||
|
|
||||||
|
console.log(`${this.key}-下次执行时间: ${nextRun.toString()}`);
|
||||||
|
|
||||||
|
// 使用setTimeout等待到下次执行时间
|
||||||
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
await loopCall(this.getInfo.bind(this), {
|
console.log("setTimeout-增量执行启动");
|
||||||
time: config.incrementFetchTime, // 5分钟间隔
|
|
||||||
pagenumber: 1,
|
// 网络连接测试
|
||||||
readyForNext: (pagenumber, result) => {
|
await this.testNetworkConnection();
|
||||||
|
|
||||||
|
await this.executeIncrement();
|
||||||
|
// 执行完后,设置每天重复执行
|
||||||
|
this.scheduleDailyIncrement();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`${this.key}-增量爬取失败:`, error.message);
|
||||||
|
// 即使出错也继续安排下一次执行
|
||||||
|
this.scheduleDailyIncrement();
|
||||||
|
}
|
||||||
|
}, timeUntilNextRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试网络连接
|
||||||
|
async testNetworkConnection() {
|
||||||
|
try {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时
|
||||||
|
|
||||||
|
const response = await fetch('https://ec.picc.com', {
|
||||||
|
method: 'HEAD',
|
||||||
|
signal: controller.signal,
|
||||||
|
mode: 'no-cors' // 不需要CORS,因为我们只是测试连接
|
||||||
|
});
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
console.log(`${this.key}-网络连接测试通过`);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`${this.key}-网络连接测试失败:`, error.message);
|
||||||
|
// 即使网络测试失败,我们也继续执行,让后续的请求自己处理错误
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行增量爬取的具体逻辑
|
||||||
|
async executeIncrement() {
|
||||||
|
console.log(`${this.key}-开始执行增量爬取...`);
|
||||||
|
try {
|
||||||
|
const result = await this.getInfo(1);
|
||||||
|
// 检查结果是否有效
|
||||||
|
if (!result || result[0]) {
|
||||||
|
console.log(`${this.key}-获取数据失败:`, result ? result[0] : "未知错误");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let newInfo = this.queue.filterNewAnnouncements(
|
let newInfo = this.queue.filterNewAnnouncements(
|
||||||
"中国人民保险",
|
"中国人民保险",
|
||||||
|
|
@ -83,30 +146,43 @@ class PICC {
|
||||||
// 存在新数据
|
// 存在新数据
|
||||||
if (newInfo.length > 0) {
|
if (newInfo.length > 0) {
|
||||||
console.log(`${this.key}-发现 ${newInfo.length} 条新数据`);
|
console.log(`${this.key}-发现 ${newInfo.length} 条新数据`);
|
||||||
// this.info.push(...newInfo);
|
|
||||||
this.queue.saveAnnouncements("中国人民保险", newInfo);
|
this.queue.saveAnnouncements("中国人民保险", newInfo);
|
||||||
// this.writeFile(this.info);
|
|
||||||
this.queue.addMessage("中国人民保险", newInfo);
|
this.queue.addMessage("中国人民保险", newInfo);
|
||||||
// 全是新数据,继续下一页
|
|
||||||
if (newInfo.length === result.info.length) {
|
|
||||||
return pagenumber + 1;
|
|
||||||
} else {
|
|
||||||
// 有部分重复数据,重新从第一页开始
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.log(`${this.key}-没有发现新数据,继续监控...`);
|
console.log(`${this.key}-没有发现新数据,继续监控...`);
|
||||||
return 1; // 重新从第一页开始
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${this.key}-数据库操作失败:`, error);
|
console.error(`${this.key}-数据库操作失败:`, error);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${this.key}-增量爬取失败:`, error);
|
console.error(`${this.key}-获取数据失败:`, error.message);
|
||||||
|
// 根据错误类型给出具体提示
|
||||||
|
if (error.code === 'ENOTFOUND') {
|
||||||
|
console.log(`${this.key}-DNS解析失败,请检查网络连接或域名是否正确`);
|
||||||
|
} else if (error.code === 'ECONNREFUSED') {
|
||||||
|
console.log(`${this.key}-连接被拒绝,请检查服务器是否正常运行`);
|
||||||
|
} else if (error.code === 'ECONNRESET') {
|
||||||
|
console.log(`${this.key}-连接被重置,请稍后重试`);
|
||||||
|
} else if (error.code === 'ETIMEDOUT') {
|
||||||
|
console.log(`${this.key}-请求超时,请检查网络连接`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置每天9点重复执行
|
||||||
|
scheduleDailyIncrement() {
|
||||||
|
// 每天间隔24小时执行一次
|
||||||
|
setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await this.executeIncrement();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`${this.key}-定时增量爬取失败:`, error);
|
||||||
|
}
|
||||||
|
}, 24 * 60 * 60 * 1000); // 24小时
|
||||||
|
|
||||||
|
console.log(`${this.key}-已设置每天9点执行增量爬取`);
|
||||||
|
}
|
||||||
|
|
||||||
async getInfo(pagenumber = 1) {
|
async getInfo(pagenumber = 1) {
|
||||||
let info = [];
|
let info = [];
|
||||||
console.log(`${this.key}-正在获取第 ${pagenumber} 页数据...`);
|
console.log(`${this.key}-正在获取第 ${pagenumber} 页数据...`);
|
||||||
|
|
@ -171,7 +247,6 @@ class PICC {
|
||||||
'Connection': 'keep-alive',
|
'Connection': 'keep-alive',
|
||||||
'Content-Type': 'application/json; charset=UTF-8',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
'Cookie': 'G_rbec_47_11_8080=22685.52745.19855.0000',
|
'Cookie': 'G_rbec_47_11_8080=22685.52745.19855.0000',
|
||||||
'Host': 'ec.picc.com',
|
|
||||||
'Origin': 'https://ec.picc.com',
|
'Origin': 'https://ec.picc.com',
|
||||||
'Referer': 'https://ec.picc.com/cms/default/webfile/ywgg1/index.html',
|
'Referer': 'https://ec.picc.com/cms/default/webfile/ywgg1/index.html',
|
||||||
'Sec-Fetch-Dest': 'empty',
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
|
@ -182,7 +257,8 @@ class PICC {
|
||||||
'Sec-Ch-Ua': '"Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141"',
|
'Sec-Ch-Ua': '"Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141"',
|
||||||
'Sec-Ch-Ua-Mobile': '?0',
|
'Sec-Ch-Ua-Mobile': '?0',
|
||||||
'Sec-Ch-Ua-Platform': "macOS",
|
'Sec-Ch-Ua-Platform': "macOS",
|
||||||
}
|
},
|
||||||
|
timeout: 10000,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
let result = res.data;
|
let result = res.data;
|
||||||
|
|
@ -194,10 +270,20 @@ class PICC {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(`${this.key}-catch`, err)
|
console.log(`${this.key}-catch`, err.message);
|
||||||
|
if (err.code === 'ENOTFOUND') {
|
||||||
|
console.log(`${this.key}-DNS解析失败,请检查网络连接或域名是否正确`);
|
||||||
|
} else if (err.code === 'ECONNREFUSED') {
|
||||||
|
console.log(`${this.key}-连接被拒绝,请检查服务器是否正常运行`);
|
||||||
|
} else if (err.code === 'ECONNRESET') {
|
||||||
|
console.log(`${this.key}-连接被重置,请稍后重试`);
|
||||||
|
} else if (err.code === 'ETIMEDOUT') {
|
||||||
|
console.log(`${this.key}-请求超时,请检查网络连接`);
|
||||||
|
}
|
||||||
return [err, null];
|
return [err, null];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new PICC("集中采购","211,213,214,215,216,217");
|
new PICC("集中采购","211,213,214,215,216,217");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue