我有一个演员,他的角色很容易爬行,大约爬行了5500个网址(urlList)
URL是结果页面,其中有一个包含json文件的脚本。 JSON中添加了一些文本,因此它不是“干净的”,因此我将其提取为const,并检查“ if”语句中是否存在匹配项。如果匹配,我会爬行。
现在。我的问题是,搜寻器统计信息+日志似乎表明所有网址都已被搜寻。问题是它们不是。在日志中,我确实看到了一些超时(下面的示例),但是这些url只被放回到了请求列表中。像“ example.com”这样的url在日志中看起来不错,并且在查找时页面上有data + json,但在结果中未输出。
我不知道出了什么问题,但直觉它的“ if”语句在做些时髦的事情。也许找到了json但尚未加载json或其他内容。
你们中有些聪明的脑袋能帮上忙吗?
统计信息示例 搜寻器的最终请求统计信息:{“ avgDurationMillis”:2554,“ perMinute”:580,“ finished”:5445,“ failed”:0:“ retryHistogram”:[5151,276,18]}
超时示例: 错误:CheerioCrawler:请求在30秒后超时。等。
const Apify = require('apify');
Apify.main(async () => {
const requestList = new Apify.RequestList({ sources: urlList })
await requestList.initialize();
const crawler = new Apify.CheerioCrawler({
requestList,
useApifyProxy: true,
handlePageFunction: async ({ $, request }) => {
const jsonString = $('script:contains("__thisvalue__")').text();
if (jsonString.match(/\[{[\d\D]*}\]/) !== null) {
const json = JSON.parse(jsonString.match(/\[{[\d\D]*}\]/));
let i = 0;
for (i = 0; i < json.length; i++) {
await Apify.pushData({
//do some crawling
url: request.url
});
}
}
},
handleFailedRequestFunction: async ({ request }) => {
console.log(`Copy of request: ${request}`);
},
});
await crawler.run();
return 'Done'
});
答案 0 :(得分:0)
发现了问题。 这行:
if (jsonString.match(/\[{[\d\D]*}\]/) !== null)
我创建了if来确保我对存在正确json字符串(例如,我要爬网的数据)的网页进行了爬网。
但是有时候脚本还没有输出数据(也许cheerio可能太快了?),所以应该有结果的页面没有被爬网,并且因为没有错误,这些URL没有被放回去在请求列表中进行另一次运行。
我只是更改了以下行,并删除了整个if。现在,如果json中没有数据,则对该URL进行3次重新评估,并且所有URL最终都将被爬网。唯一需要注意的是,我现在在日志中出现 TypeError错误:无法读取null的属性'xyz'。
const jsonString = JSON.parse($('script:contains("__thisvalue__")').text().match(/{[\d\D]*}}/))