美文网首页爬虫(Java...
基于Nodejs的爬虫框架Tai-Spider

基于Nodejs的爬虫框架Tai-Spider

作者: 敬亭阁主 | 来源:发表于2021-11-10 09:01 被阅读0次

    鼎鼎大名的Scrapy是基于Python的爬虫框架,Tai-Spider就是基于Nodejs的Scrapy,下面我们就来看看这个框架有哪些能力吧。

    官方提供了爬虫示例项目 tai-spider-example

    安装

    直接使用 npm 或者 yarn 安装即可

    npm install tai-spider
    

    或者

    yarn add tai-spider
    

    编写第一个爬虫

    官方示例采用了和Scrapy一样的例子,即在spider目录下创建quotes.js,该爬虫继承了TaiSpider,其代码如下所示:

    'use strict'
    
    const { TaiSpider, ItemLoader } = require('tai-spider');
    
    class QuotesSpider extends TaiSpider {
    
        constructor(options = {}) {
            super(options);
            this.name = 'quotes';
            this.debug = true;
            this.start_urls = [
                'https://quotes.toscrape.com/page/1/',
            ];
        }
    
        *parse(response) {
            for (let ele of response.css('div.quote')) {
                yield {
                    'text': response.css('span.text', ele).text(),
                };
            }
        }
    }
    
    module.exports = QuotesSpider;
    

    在这个例子里 QuotesSpider 作为 TaiSpider 的子类,定义并实现了一些属性和方法:

    • name:用于标识spider,它在项目中必须是唯一的,也就是说,不能为不同的spider设置相同的名称。

    • start_urls:起始urls,后续请求将从这些初始请求连续生成。

    • parse():该方法将被调用来处理每个请求下载的响应,response参数是Response类的一个实例,它提供了一些便利的方法来处理页面元素。parse方法通常用于解析响应,将抓取的数据提取为json对象、查找要跟踪的新URL,并从中创建新请求。

    运行Spider

    为了运行刚刚编写好的spider,你需要进入项目的顶层目录,并执行如下命令:

    taispider run quotes
    

    这个命令将运行我们刚刚编写的名为 quotes 的爬虫,它将向 quotes.toscrape.com 发送一些请求,我们可以得到类似下面的输出:

    run spider: quotes
    start url: https://quotes.toscrape.com/page/1/
    [2021-11-06T09:31:44.570] [DEBUG] taispider - seenreq is initialized.
    [2021-11-06T09:31:46.991] [DEBUG] taispider - connect to a new https://quotes.toscrape.com
    [2021-11-06T09:31:48.027] [DEBUG] taispider - Http2 session https://quotes.toscrape.com connection init
    [2021-11-06T09:31:48.675] [DEBUG] taispider - https://quotes.toscrape.com/page/1/ stream ends
    [2021-11-06T09:31:48.676] [DEBUG] taispider - Got https://quotes.toscrape.com/page/1/ (11053 bytes)...
    [2021-11-06T09:31:48.694] [DEBUG] taispider - Queue size: 0
    

    parse 方法中你可以通过css表达式来对HTML元素进行选取,具体的css表达式规则可以参考 cheerio.

    你也可以将抓取到的数据保存到文件中而不是打印到屏幕上,你只需要加上如下的命令行参数即可:

    taispider run quotes -o result.jl
    

    递归抓取页面中的链接

    parse() 方法不仅用于抓取页面中的数据,还可以获取下一步抓取的链接。可以使用 follow 或者 follow_all 生成新的抓取请求,同时还允许你为这个请求指定新的回调处理函数。

    在下面这个例子中,就创建了一个名为 parseAuthor 的新方法来处理新的author页面:

    'use strict'
    
    const { TaiSpider, ItemLoader } = require('tai-spider');
    
    class QuotesSpider extends TaiSpider {
    
        constructor(options = {}) {
            super(options);
            this.name = 'quotes';
            this.debug = true;
            this.start_urls = [
                'https://quotes.toscrape.com/page/1/',
            ];
        }
    
        *parse(response) {
            for (let ele of response.css('div.quote')) {
                yield {
                    'text': response.css('span.text', ele).text(),
                };
                yield* response.follow_all(response.css('span a', ele), this.parseAuthor);
            }
        }
    
        *parseAuthor(response) {
            const extract_with_css = (query) => {
                return _.trim(response.css(query).text());
            }
    
            yield {
                'name': extract_with_css('h3.author-title'),
                'birthdate': extract_with_css('.author-born-date'),
                'bio': extract_with_css('.author-description'),
            }
        }
    
    }
    
    module.exports = QuotesSpider;
    

    使用model

    在parse方法中除了可以直接使用json对象,也可以使用 ItemLoader 来简化数据的抽取,通过预先定义好model,你就可以简单地仅使用 load_item 方法就可以完成数据的抽取。

        *parseAuthor(response) {
            const loader = new ItemLoader(response, require('../model/author'));
            yield loader.load_item();
        }
    

    model/author.js

    const Item = require('tai-spider').Item;
    
    module.exports = new Item({
        name: 'h3.author-title',
        birthdate: {
            value: '.author-born-date',
            type: 'date',
        },
        bio: '.author-description',
    });
    

    下载图片文件

    有时我们需要下载大量的图片文件,使用 TaiSpider 框架,可以仅仅通过设置几个简单的属性就可以完成图片文件的下载。

    • IMAGES_STORE 用于指定输出路径
    • Image 对象用于指定输出图片的属性,包括 url, type, filenamebody

    如果没有给出 filename 属性,框架会自动根据 url 生成MD5值来作为文件名。

    'use strict'
    
    const { TaiSpider } = require('tai-spider');
    const { Image } = require('tai-spider').types;
    
    class ImageSpider extends TaiSpider {
    
        constructor(options = {}) {
            super(options);
            this.name = 'image';
            this.debug = true;
            this.start_urls = [
                'https://www.mmonly.cc/gxtp/',
            ];
            this.envs['ECHO'] = false;
            this.envs['IMAGES_STORE'] = 'output';
        }
    
        *parse(response) {
            for (let ele of response.css('div.item')) {
                let imageEle = response.css('img', ele)[0];
                yield response.follow(imageEle.attribs['src'], this.parseImage, { filename: imageEle.attribs['alt'] + '.jpg' });
            }
        }
    
        *parseImage(response) {
            yield new Image({
                url: response.options.uri,
                type: 'jpg',
                filename: response.options.filename,
                body: response.body,
            });
        }
    }
    
    module.exports = ImageSpider;
    

    执行上述爬虫,你就可以在 output 目录下得到所有下载的图片文件。

    这么好的爬虫框架,赶紧开始用起来吧,Github地址在这里: Tai-Spider

    相关文章

      网友评论

        本文标题:基于Nodejs的爬虫框架Tai-Spider

        本文链接:https://www.haomeiwen.com/subject/fesbzltx.html