IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    merrynode发表于 2017-02-21 13:41:38
    love 0

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

    下载表情包到本地

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

    alt

    我们首先判断本地是否存在这个文件,如果存在则跳过下载,如果不存在, 我们就创建一个可写的文件 stream ,然后请求表情包地址,并 pipe 到 stream, 监听 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);
        }
    })();
    

    我们来运行下我们的项目

    alt

    完整代码



沪ICP备19023445号-2号
友情链接