Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
186 lines (124 loc) · 5.72 KB

File metadata and controls

186 lines (124 loc) · 5.72 KB
Copy raw file
Download raw file
Outline
Edit and raw actions

爬虫集成

本功能可以将多个爬虫以插件的形式集成为一个爬虫,常用于采集周期一致,需求一致的,但需要采集多个数据源的项目

使用场景举例

如我们需要做舆情数据,需要采集多个新闻网站,如何开发爬虫呢?

常规做法

每个新闻源写一个或多个爬虫,如下: -w526 这样每个爬虫之间比较独立,如果有上百个数据源,需要启动上百个爬虫脚本,不便于管理

本框架做法

本框架支持上述的常规做法同时,支持了更友好的管理方式,可将这些爬虫集成为一个爬虫,我们只需维护这一个爬虫即可,当然也支持分布式。

-w528

注: Spider爬虫与BatchSpider爬虫支持集成,AirSpider不支持

Spider 集成

支持分布式采集

以采集新浪和腾讯新闻为例

1. 编写解析器

新浪解析器

import feapder


class SinaNewsParser(feapder.BaseParser):
    def start_requests(self):
        """
        注意 这里继承的是BaseParser,而不是Spider
        """
        yield feapder.Request("https://news.sina.com.cn/")

    def parse(self, request, response):
        title = response.xpath("//title/text()").extract_first()
        print(title)

腾讯解析器

import feapder


class TencentNewsParser(feapder.BaseParser):
    """
    注意 这里继承的是BaseParser,而不是Spider
    """
    def start_requests(self):
        yield feapder.Request("https://news.qq.com/")

    def parse(self, request, response):
        title = response.xpath("//title/text()").extract_first()
        print(title)

注意:之前我们爬虫继承的是Spider,这里因为要集成,所以要继承BaseParser

BaseParser只是一个解析器,不具备任何调度功能,我们写好每个网站的解析器,然后集成到爬虫中,由这个爬虫调度这些解析器去解析对应的网站

BaseParser 所支持的函数与Spider一致,因此集成时爬虫代码无需更改,只需要将继承类改为BaseParser即可

2. 集成解析器

from feapder import Spider

spider = Spider(redis_key="feapder:test_spider_integration")
# 集成
spider.add_parser(SinaNewsParser)
spider.add_parser(TencentNewsParser)

spider.start()

add_parser方法可以集成解析器,只需要将每个解析器的类名传进来即可

完整代码示例:Spider集成

BatchSpider 集成

支持批次采集、支持分布式

以采集新浪和腾讯新闻为例

1. 编写解析器

新浪解析器

import feapder


class SinaNewsParser(feapder.BatchParser):
    """
    注意 这里继承的是BatchParser,而不是BatchSpider
    """
    
    def start_requests(self, task):
        task_id = task[0]
        url = task[1]
        yield feapder.Request(url, task_id=task_id)

    def parse(self, request, response):
        title = response.xpath("//title/text()").extract_first()
        print(self.name, title)
        yield self.update_task_batch(request.task_id, 1)

腾讯解析器

import feapder


class TencentNewsParser(feapder.BatchParser):
    """
    注意 这里继承的是BatchParser,而不是BatchSpider
    """

    def start_requests(self, task):
        task_id = task[0]
        url = task[1]
        yield feapder.Request(url, task_id=task_id)

    def parse(self, request, response):
        title = response.xpath("//title/text()").extract_first()
        print(self.name, title)
        yield self.update_task_batch(request.task_id, 1)

注意:之前我们爬虫继承的是BatchSpider,这里因为要集成,所以要继承BatchParser

BatchParser只是一个解析器,不具备任何调度功能,我们写好每个网站的解析器,然后集成到爬虫中,由这个爬虫调度这些解析器去解析对应的网站

BatchParser 所支持的常用函数与BatchSpider一致,但BatchParser不支持任务初始化函数init_task。任务初始化为BatchSpider的每个批次开始时的逻辑,所有批次解析器共用一个init_task

2.集成

from feapder import BatchSpider


def batch_spider_integration_test(args):
    """
    BatchSpider集成测试
    """

    spider = BatchSpider(
        task_table="batch_spider_integration_task",  # mysql中的任务表
        batch_record_table="batch_spider_integration_batch_record",  # mysql中的批次记录表
        batch_name="批次爬虫集成测试",  # 批次名字
        batch_interval=7,  # 批次时间 天为单位 若为小时 可写 1 / 24
        task_keys=["id", "url", "parser_name"],  # 集成批次爬虫,需要将批次爬虫的名字取出来,任务分发时才知道分发到哪个模板上
        redis_key="feapder:test_batch_spider_integration",  # redis中存放request等信息的根key
        task_state="state",  # mysql中任务状态字段
    )

    # 集成
    spider.add_parser(SinaNewsParser)
    spider.add_parser(TencentNewsParser)

    if args == 1:
        spider.start_monitor_task()
    elif args == 2:
        spider.start()

任务表:

-w444

任务表里需要有一个字段存储解析器的类名,与对应的任务关联,在我们取任务时携带这个类名,这样框架才知道这条任务归属于哪个解析器

这里存储解析器名字的字段为parser_name

完整代码示例:批次爬虫集成

Morty Proxy This is a proxified and sanitized view of the page, visit original site.