前言

这个小图很久以前就有了,当时好多人都去写代码爬这个图,遗憾啊,我没去凑热闹。今天看了下发现有对应的 JSON 接口,小图片有 517 张,想想写个代码都抓下来看看吧。

食用方法

使用 Chrome 浏览器打开 B 站任意网址,打开 开发者工具 -> console,粘贴下面的代码回车运行:
( 不方便复制的可以去 Github Gist 查看:https://gist.github.com/maicong/cd2744f8990530407d9b1cb3caefb330 )

((url, delay) => {
    let starTime = new Date().getTime();
    let xhr = new XMLHttpRequest();
    let times = [];
    let style = document.createElement('style');
    style.textContent = 'body { display: flex; flex-wrap: wrap; } div { text-align: center; padding: 0.5rem; margin: 1rem; border: 1px solid #ddd; }';
    document.head.appendChild(style);
    document.body.innerHTML = '';
    xhr.open('GET', url, true);
    xhr.onload = event => {
        if (xhr.status >= 200 && xhr.status < 400) {
            console.debug(`资源已加载,耗时 ${new Date().getTime() - starTime} ms,开始获取...`);
            (loadImg = (i, srcs) => {
                (promise = (src, title, timeStamp) => new Promise(resolve => {
                    let img = new Image();
                    let div = document.createElement('div');
                    let p = document.createElement('p');
                    p.textContent = title;
                    img.src = src;
                    img.alt = title;
                    img.onload = newEvent => {
                        setTimeout(() => {
                            let usedTime = newEvent.timeStamp - timeStamp;
                            usedTime = Math.floor(i > 0 ? usedTime - delay : usedTime);
                            times.push(usedTime);
                            console.info(`第 ${i + 1} 张获取成功,耗时 ${usedTime} ms`, img.src);
                            div.appendChild(img);
                            div.appendChild(p);
                            document.body.appendChild(div);
                            resolve(newEvent.timeStamp);
                        }, delay);
                    };
                    img.onerror = err => {
                        console.warn(`第 ${i + 1} 张获取失败`, img.src);
                        resolve(err.timeStamp);
                    };
                }).then(timeStamp => {
                    if (i === srcs.length - 1) {
                        let min = Math.min.apply(null, times);
                        let max = Math.max.apply(null, times);
                        let avg = (times.reduce((p, c) => Number(p) + Number(c)) / times.length).toFixed(0);
                        console.debug(`图片下载完毕,最快用时 ${min} ms,最慢用时 ${max} ms,平均用时 ${avg} ms`);
                    } else {
                        i += 1;
                        promise(srcs[i].icon, srcs[i].title, timeStamp);
                    }
                }))(srcs[i].icon, srcs[i].title, event.timeStamp);
            })(0, (JSON.parse(xhr.responseText)).fix);
        }
    };
    xhr.send();
})('http://www.bilibili.com/index/index-icon.json', 100);

更多示例

微信表情包

将这行代码复制到 Chrome 地址栏直接体验:

data:text/html, <!DOCTYPE html><html><head></head><body><h2>loading...</h2><script src='https://cdn.rawgit.com/maicong/38bc28e509d14097f4ba5f7374091624/raw/d73ed0a385f2c4a10a0d3bf18b127ac40bf5d0d8/wechatEmoticon.js'></script></body></html>

Github Gist:

https://gist.github.com/maicong/38bc28e509d14097f4ba5f7374091624

代码:

((url, delay) => {
    let starTime = new Date().getTime();
    let xhr = new XMLHttpRequest();
    let times = [];
    let style = document.createElement('style');
    style.textContent = 'body { background: #fff; } div { display: inline-flex; padding: 0.5rem; } div img { box-shadow: 0 0 5px 0 #8e8e8e; }';
    document.head.appendChild(style);
    document.body.innerHTML = '';
    xhr.open('GET', url, true);
    xhr.onload = event => {
        if (xhr.status >= 200 && xhr.status < 400) {
            console.debug(`资源已加载,耗时 ${new Date().getTime() - starTime} ms,开始获取...`);
            (loadImg = (i, srcs) => {
                (promise = (src, timeStamp) => new Promise(resolve => {
                    let img = new Image();
                    let div = document.createElement('div');
                    img.src = src;
                    img.onload = newEvent => {
                        setTimeout(() => {
                            let usedTime = newEvent.timeStamp - timeStamp;
                            usedTime = Math.floor(i > 0 ? usedTime - delay : usedTime);
                            times.push(usedTime);
                            console.info(`第 ${i + 1} 张获取成功,耗时 ${usedTime} ms`, img.src);
                            div.appendChild(img);
                            document.body.appendChild(div);
                            resolve(newEvent.timeStamp);
                        }, delay);
                    };
                    img.onerror = err => {
                        console.warn(`第 ${i + 1} 张获取失败`, img.src);
                        resolve(err.timeStamp);
                    };
                }).then(timeStamp => {
                    if (i === srcs.length - 1) {
                        let min = Math.min.apply(null, times) / 1000;
                        let max = Math.max.apply(null, times) / 1000;
                        let sum = Math.round(times.reduce((p, c) => Number(p) + Number(c))) / 1000;
                        let avg = Math.round(sum / times.length);
                        console.debug(`图片下载完毕,用时 ${sum} s, 最快 ${min} s,最慢 ${max} s,平均 ${avg} s`);
                    } else {
                        i += 1;
                        promise(srcs[i].url, timeStamp);
                    }
                }))(srcs[i].url, event.timeStamp);
            })(0, (JSON.parse(xhr.responseText)));
        }
    };
    xhr.send();
})('https://raw.githubusercontent.com/spacelan/wechat-emoticon/master/emoticons.json', 50);

无图无真相

效果图

效果图

小图片合集

点击新窗口打开看大图

小图片

带符号 * 的表示必填项
  1. YANGNOW
    YANGNOW

    跑下来报错了

    回复
  2. YANGNOW
    YANGNOW

    厉害了我的哥

    回复
  3. 夏日草博客
    夏日草博客

    看得晕晕呼呼的。

    回复
  4. Sakura
    Sakura

    葱哥,我能把自己的表情包也用你这段代码的方式做吗?求指导,谢谢

    回复
  5. 商学院
    商学院

    普通人上B站找资源,程序猿上B站是研究代码,也是牛人啊

    回复
  6. 任务易
    任务易

    技术贴啊 强迫症症的看着舒服

    回复
  7. 胡杨
    胡杨

    极致强迫症患者

    回复
  8. Akon uncle
    Akon uncle

    对于强迫症患者来说,效果图的动画看起来好爽啊

    回复
  9. Tokin
    Tokin

    比肩火车头的爽快感

    回复
    1. MaiCong
      MaiCong博主

      有个微信表情包的接口,几千张表情,爬起来更酸爽。

      回复
  10. 不亦乐乎
    不亦乐乎

    眼花缭乱

    回复
    1. MaiCong
      MaiCong博主

      可以整理下。

      回复