0

我有一个带有cheerio-crawler 的演员,它可以抓取大约5500 个网址(urlList)的列表

url 是结果页面,其中有一个包含 json 文件的脚本。json 中添加了一些文本,因此它不是“干净的”,因此我将其提取到 const 中,并检查“if”语句中是否存在匹配项。如果有比赛,我会爬。

现在。我的问题是爬虫统计信息+日志,似乎表明所有网址都已被爬取。问题是他们不是。在日志中,我确实看到了一些超时(下面的示例),但是这些 url 只是放回了请求列表中。像“example.com”这样的 url 在日志中似乎很好,并且在查找时页面上有 data + json,但它没有在结果中输出。

我不知道出了什么问题,但有一种预感,它的“if”语句正在做一些时髦的事情。也许找到了 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'

});
4

1 回答 1

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]*}}/))
于 2019-12-09T11:55:05.137 回答