利用 mongodb 保存抓取图片的地址

522 阅读2分钟
原文链接: www.qdfuns.com

接前一篇文章:
我们想抓取的图片列表是这样的:

然后每个图片都能点,点进去后是 带分页的大图

一开始我的思路是遍历列表页, 然后去请求每个detail页, detail 做一个递归,最后把所有的图片都保存到一个 imgList里面。
然后保存并下载这个list。
但是实现后发现一个问题,就是有时候循环列表页的时候遇到某种异常报错了,比如说 第十个detail 可能有一个分页页面找不到。那我们只能再来一遍,这很不友好。
所以我决定每次爬取完一个detail后 ,都保存到数据库,然后再爬取下一个。这样即使中间断了,也损失不大,因为之前的你已经保存过了。
那下次开始的时候我先去数据库查询有没有未下载的图片,有的话直接下载,没有就开始继续爬。
安装mongodb请百度。接下来安装 node 驱动包 mongodb
链接数据库操作:

数据库保存的字段类似这样:

JavaScript7 1
[
2
    {
3
        url: '图片地址',
4
        time: '保存时间',
5
        isDownload: false  //'是否下载到本地'
6
    }
7
]

刚开始保存的时候 isDownload 都是 false, 等最后下载图片的时候,完成一个 就更新数据库把 isDownload 变成 true 代码类似这样
插入图片

JavaScript33 1
insert(list){ 
2
        return new Promise((resolve, reject) => {
3
            this.getMongo().then((db) => {
4
                let collection = db.collection(documents),
5
                    doneNum = 0;
6
                let done = () => {
7
                    if (doneNum == list.length) {
8
                        resolve();
9
                    }
10
                };
11
                if(!list.length){
12
                    reject('图片列表为空');
13
                    return;
14
                }
15
                list.forEach(data =>{
16
                    collection.updateOne(data,{
17
                        $set: {
18
                            time: new Date().getTime()
19
                        }
20
                    },{
21
                        upsert: true
22
                    }, (err, docs) => {
23
                        if (err) {
24
                            reject(err);
25
                            return;
26
                        }
27
                        doneNum ++;
28
                        done();
29
                    });
30
                });
31
            })

插入的时候用的也是updateOne方法, 然后第三个参数upsert:true 表示没有就插入,有就更新。这样不会插入重复的图片
更新图片:

JavaScript14 1
this.getMongo().then((db) => {
2
                let collection = db.collection(documents);
3
                collection.findOneAndUpdate(data, {$set: {isDownload: true}}, {
4
                    returnOriginal: false,
5
                    //sort: [[a,1]],
6
                    upsert: true
7
                }, (err, docs) => {
8
                    if (err) {
9
                        reject(err);
10
                        return;
11
                    }
12
                    resolve();
13
                });
14
            })
更新只是把当前对象的 isDownload 变成true 。
最后放上项目地址