【问题标题】:Nodejs/nestjs: Getting a 13s response time from my multiple crawlersNodejs/nestjs:从我的多个爬虫中获得 13 秒的响应时间
【发布时间】:2019-09-30 20:27:20
【问题描述】:

我正在构建一个类似于 Flipboard 简报移动应用的报纸应用!使用 nodejs nestjs 框架。

所以我爬入多个网站以获取数据,最后我得到了一个数组,其中仅从每个网站收集的第一页就有超过 60 个项目,响应时间在 10 秒到 15 秒之间,这对于 3 来说是不可接受的网站!!!!

我搜索了这个,我发现nestjs 提供了一个缓存服务,它缓存了20 毫秒的结果,但是!

我没有使用任何类型的数据库,因为我没有抓取数据!只是 iframe 的标题和 URL

我的问题是:

  1. 如何分页到每页 60 个项目,最后从我的爬虫发出新的下一页请求。
  2. 第一个用户每 6 小时将面临 15 秒的响应时间(我的缓存端),那么如何使服务器自动缓存数据而不等待请求

爬虫代码:(我有 3 个类似的函数,只是 CSS 选择器改变了)

async getArticlesFromTechWD(page: number) {
    const html = await get('https://www.tech-wd.com/wd/category/news/page/' + page);

    // Cheerio
    let $ = load(html);

    function formatingDate(date) {
        let months = ["يناير", "فبراير", "مارس", "إبريل", "مايو", "يونيو",
            "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"
        ];

        date = date.replace('،', '').split(' ');
        const year = date[2];
        const month = (months.indexOf(date[1]) + 1).toString().length == 1 ? '0' + (months.indexOf(date[1]) + 1) : (months.indexOf(date[1]) + 1)
        const day = date[0];

        return `${year}-${month}-${day}`;
    }

    const articles = $('#masonry-grid .post-element').map(function () {
        return {
            title: $('.thumb-title', this).text().trim(),
            date: formatingDate($('.date', this).text().trim()),
            url: $('.thumb-title a', this).attr('href'),
            image: $('.slide', this).css('background-image').replace('url(', '').replace(')', '').replace(/\"/gi, ""),
            src: 'www.tech-wd.com'
        }
    }).get();

    return articles;
}

将所有爬虫数据合并到一个数组中:

async getAllArticles(page: number, size: number) {

    const skip = size * (page - 1);

    // First crawler ( has an optional page pram default is page 1 )
    const unlimitTech = await this.getArticlesFromUnlimitTech();

    // Second crawler ( has an optional page pram default is page 1 )
    const tectWd = await this.getArticlesFromTechWD();

    // Merge them and sorted by date ( DESC )
    const all = unlimitTech.concat(tectWd).sort(() => Math.random() - 0.5);

    return all;

}

【问题讨论】:

  • 你真的应该展示一些代码。
  • 抱歉,我写的问题太匆忙了!我已经用一些代码更新了这个问题......感谢回复

标签: javascript node.js web-scraping web-crawler cheerio


【解决方案1】:

而不是一次一个:

const unlimitTech = await this.getArticlesFromUnlimitTech();
const tectWd = await this.getArticlesFromTechWD();

你可以同时做这两件事:

const [unlimitTech, tectWd] = await Promise.all([
  this.getArticlesFromUnlimitTech(),
  this.getArticlesFromTechWD()
])

【讨论】:

    【解决方案2】:

    诀窍是一次做多件事。开始您的所有请求,然后在最后对每个请求进行await。至少您的时间安排听起来像是在等待每个请求完成后再开始下一个请求。

    【讨论】:

    • 这在 NodeJS 中是不可能的,因为它是单线程的,所以它必须同时完成每个任务
    • @hesham 节点是异步的,这意味着它可以在 IO 阻塞时做其他事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 2016-11-09
    • 2023-03-05
    相关资源
    最近更新 更多