Quantcast
Viewing all articles
Browse latest Browse all 14821

【爬虫教程】从零开始写一个表情包爬虫二

第一部分我们已经完成了表情包链接的获取,接下来我们开始批量下载表情包到本地。

下载表情包到本地

观察表情包地址我们发现表情包后面22位就是它完整且唯一的文件名。

Image may be NSFW.
Clik here to view.

我们首先判断本地是否存在这个文件,如果存在则跳过下载,如果不存在, 我们就创建一个可写的文件 stream ,然后请求表情包地址,并 pipestream, 监听 close事件,触发时完成Promise

function downloadMeMe (url) {
        console.log(`下载: ${url}`);
        let filePath = `./memes/${url.substr(-22)}`;    // 取到后22位作为文件名
        let stream   = fs.createWriteStream(filePath);  // 创建一个可写 stream 对象
        // 请求表情包地址,并 pipe 到刚才创建的 stream 对象
        request.get(url).pipe(stream);
}

限流器

假设我们打开表情包页面,他会同时请求一整页的表情包,所以我们只需要限制批量请求之间的间隔就好。 写个限流器,控制单次请求数,访问频率过快会导致爬虫被发现。你也可以设置随机延时。

function timerChunk(any, fn, limit, wait = 0) {
    let run = async function () {
        if (!any.length) {
            return;
        }

        // 延时等待 这里是随机0到wait毫秒
        await (new Promise((resolve, reject) => setTimeout(resolve, ~~(Math.random() * wait))));

        let params = any.splice(0, limit);              // 每次取出 limit 数量的任务
        params.forEach((param) => fn(param));
        return run();
    }

    return run();
}

组装函数

最后步骤就是搭积木把函数拼起来

(async function crawler() {
    let keyword = '单身狗';
    try {
        // 获取该关键字所有的表情包链接
        let links = await getLinksByPage(keyword, 1);
        // 下载表情包到本地
        await timerChunk(links, downloadMeMe, 5, 3000);
        console.log('完成!');
    } catch (err) {
        console.error(err);
    }
})();

我们来运行下我们的项目

Image may be NSFW.
Clik here to view.

完整代码


Viewing all articles
Browse latest Browse all 14821

Trending Articles