鼎鼎大名的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
,filename
和body
如果没有给出 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