当前位置: 首页 > 工具软件 > Tai > 使用案例 >

基于Node的爬虫框架Tai-Spider

司徒池暝
2023-12-01

大家都知道基于Python的爬虫框架Scrapy,Tai-Spider就是Scrapy基于Node的同人作品,下面我们就来看看这个框架有哪些能力吧。

根据官方介绍,Tai-Spider是基于node-crawler进行改造,并使用了和scrapy类似的APIs。

Tai Spider is grown from node-crawler, and has similar APIs with 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

 类似资料: